.NET生命周期支持与EOL后安全解决方案

本文深入探讨.NET官方支持政策、EOL后安全风险,并介绍HeroDevs的Never Ending Support解决方案,通过实际案例展示如何保护EOL .NET应用免受CVE-2025-55315等高危漏洞威胁。

.NET,支持生命周期与漏洞管理

.NET 10刚刚发布,虽然一些人对性能改进和新功能感到兴奋,但另一些人无疑会担心他们当前使用的.NET版本在支持到期前的倒计时。

.NET每年11月发布新版本,分为长期支持(LTS)版本和标准期限支持(STS)版本:

  • 奇数版本是标准期限支持(STS),获得微软2年支持
  • 偶数版本是长期支持(LTS),获得微软3年支持

LTS和STS版本在质量上没有区别,唯一的区别是微软支持该版本直到生命周期结束(EOL)的时间长短。

什么是"受支持"?

大多数人对"受支持"有直观理解,通常是"如果有错误,会被修复"。但微软在其政策中非常具体地定义了支持的含义。

LTS和STS版本的支持都有两个"阶段":

  • 主动支持:在主动支持期间,.NET版本会更新以改进功能能力并缓解安全漏洞
  • 维护支持:在维护支持期间,.NET版本仅更新以缓解安全漏洞

维护支持期是任何版本支持的最后6个月。

在大多数支持时间线中,您可以期望看到安全漏洞修复和"改进功能能力的更新"。被视为"功能能力改进"的范围实际上相当广泛:

  • 解决报告的崩溃
  • 解决严重性能问题
  • 解决常见场景中的功能错误
  • 支持新的操作系统版本或新硬件平台

您每个月都打补丁,对吧?

.NET 10于11月11日发布,但一个月后,我确信会有针对运行时、ASP.NET Core、.NET SDK以及构成微软提供的基础.NET生态系统的各种其他包的补丁发布。

即使您使用受主动支持的.NET版本,只有使用最新修补版本才能获得支持。

具体来说,在撰写本文时,.NET 9的最新发布版本是:

  • .NET 9 SDK 9.0.307
  • .NET Runtime 9.0.11

如果您今天有使用.NET 9的应用程序,但没有运行最新的.NET 9补丁版本(9.0.11),那么您使用的是不受支持的.NET版本。下个月可能会有9.0.12版本取代9.0.11!

只有所有.NET组件的最新补丁版本才受支持。截至目前,这意味着分别是.NET 8、.NET 9和.NET 10的最新补丁。

综合起来,如果您想坚持使用仅受微软支持的.NET版本,这意味着每个月您至少需要:

  • 更新用于构建.NET应用程序的.NET SDK
  • 更新用于部署和运行应用程序的.NET运行时

如果您不能每月更新这些版本,那么您将不会使用微软支持的.NET版本。

好消息是,.NET的补丁更新通常非常容易应用。它们很少包含破坏性问题或需要大量工作。

但最终不会有更多补丁版本,您使用的.NET版本将失去支持,然后怎么办?

运行不受支持的.NET版本是在玩火

从根本上说,从技术角度来看,当.NET版本失去官方支持时,什么也不会发生。一切照常工作,就像以前一样。

然而,根据您的监管环境,您可能会发现自己不再合规,带来所有潜在的财务或法律影响。

即使您不在受监管的环境中,您仍然有可能在任何时候遇到大问题:当您(或其他人)在您不受支持的.NET版本中发现问题时。

这正是许多人最近发现自己所处的情况,当请求走私安全漏洞CVE-2025-55315被宣布时。此漏洞非常严重(9.9严重性),因为它允许攻击者潜在地绕过安全控制、窃取数据、以其他用户身份登录、执行注入攻击等,所有这些都依赖于请求走私。

希望您能理解……情况不妙。

该漏洞为.NET 8、.NET 9和.NET 10发布了补丁,因为这些版本仍在支持中。但基本上所有.NET版本都易受攻击;至少是.NET Core 3.1、.NET 5、.NET 6和.NET 7。

所有这些都让那些运行不受支持.NET版本的组织陷入困境。如果您继续运行不受支持的.NET版本,那么您的应用程序就有一个已知的9.9严重性漏洞。另一种选择是执行应用程序的主要版本更新以使用受支持的.NET版本,但这可能说起来容易做起来难……

如果您使用.NET 6,那么还有另一个选择,HeroDevs,我们很快就会谈到!😅

主要版本更新的困难

许多开发人员期待新的.NET主要版本。新的.NET主要版本通常意味着:

  • 性能改进:令人难以置信的是,每个新版本的.NET都比前一个版本更快
  • 新功能:主要版本通常意味着新功能
  • 对新平台的支持:一些主要版本包括对新操作系统和CPU架构的支持

但主要升级并不总是胆小者能承受的。我们已经从.NET Core 1.0、.NET Core 2.0和.NET Core 3.1之间的巨大转变走了很长的路,但执行主要版本更新仍然存在许多潜在风险,特别是从组织的角度来看。

例如:

  • 破坏性变更:主要版本更新不可避免地带来各种破坏性变更
  • 行为变化:即使更新中的更改不被视为破坏性,它们仍可能导致行为差异
  • 工具升级:构建新版本的.NET可能需要您更新各种工具
  • 法规合规性:根据您的环境,您可能需要重新认证所有更新到新主要版本的应用程序
  • 内部支持:如果您有支持其他团队的"平台"团队,那么开发人员需要一定程度的经验和学习
  • 机会成本:花在迁移到较新.NET版本上的时间就是没有实现新功能或满足客户需求的时间

更新到新的主要版本显然有许多优点,但对于一些组织和应用程序来说,性能改进和新功能的好处根本不足以抵消执行迁移相关的风险和成本。

但这些组织也不能承受停留在不受支持的版本上,这会导致监管问题,或者面临处理未修补的CVE(如CVE-2025-55315)的风险。

那么,可怜的.NET使用组织该怎么办?

为什么不直接付费购买支持?

现在我们谈到我的观点:如果主要版本更新太痛苦,就推迟它,只为旧.NET版本付费购买支持。

正如我在上一节中讨论的,组织通常不想进行主要版本更新,因为前面描述的困难。组织进行这些主要更新是因为他们必须这样做,以确保他们能够解决出现的任何安全问题,并确保他们符合监管要求。

一个典型的例子是一个不再积极开发的应用程序。在这种情况下,执行主要版本更新的相关成本可能超过好处,特别是如果这触发了任何类型的合规性或审计要求。但让应用程序不受支持也不是一个选择。

组织不想更新到新的.NET主要版本这一事实有时表现为向微软恳求延长.NET的支持窗口。许多组织渴望Windows或.NET Framework的十年支持,并问"为什么现代.NET不能那样"。

但问题是,即使有十年的支持,组织也不想升级!Windows 10在2025年10月(发布10年后)不再受支持,但它仍占活动Windows版本的40%!组织讨厌变化……

当然,Windows 10在2025年10月结束了标准支持,但您仍然可以为Windows 10付费购买扩展支持并接收安全更新。

所以似乎简单的答案是"如果您不想更新,只需付费购买支持"。

其他生态系统中的EOL后支持

在产品官方支持结束后付费购买支持的模式在其他生态系统中也很常见。以Java为例。多个供应商生产Open JDK发行版,并为它们提供实质性的支持期限,但您通常需要为此付费:

供应商 支持的JDK 支持期限
Red Hat 8, 11, 17, 21(因RHEL版本而异) 通常长达8年以上(带RHEL订阅)
Microsoft 11, 17, 21(基于Microsoft支持政策) 通常6年以上
Ubuntu 8, 11, 17, 21(因Ubuntu版本而异) 12年(带扩展支持)

类似地,Java Spring和Spring Boot框架最初为版本提供免费支持,然后通过VMware Tanzu提供付费选项。

然而,也有大量第三方公司愿意为Spring Framework和Spring Boot提供付费支持,甚至超过这些时间线(包括HeroDevs!)

愿意在产品正式EOL后付费购买支持的情况并不局限于Java生态系统。您可以找到各种前端框架的EOL支持,如Angular、AngularJS、Vue,甚至Bootstrap。

那么为什么.NET不行呢?

.NET中的EOL后支持

那么为什么有些公司似乎对为.NET付费购买EOL后支持如此犹豫?我推测部分原因是因为微软通常愿意提供非常长的支持窗口。

以.NET Framework为例;.NET Framework 3.5仍然受支持——直到2029年才EOL!

我怀疑另一个主要原因是,一些.NET组织根本不知道付费购买EOL后支持是一个选择!据我所知,微软没有明确认可甚至没有提到这对生态系统是可用的,微软相关机构如.NET基金会也没有。

我真的不知道他们为什么不这样做,这对我来说似乎是双赢的场景。🤷

所以请考虑这是我的公共服务公告:

如果您仍在.NET 6上运行应用程序,或者如果您担心.NET 8明年支持结束,别担心。切换到.NET 6(或明年的.NET 8)的EOL后支持构建,您将收到安全修复,而无需经历昂贵的主要版本更新。

这是HeroDevs为其.NET支持所做的宣传:

  • 安全修复:每次HeroDevs发现、验证和修复安全问题时,都会发布新版本的NES for .NET
  • 直接兼容:直接替换您的框架——无需迁移,无需重写,只需持续支持
  • SLA合规性:HeroDevs提供SLA,通过根据行业标准法规(包括SOC 2、FedRAMP、PCI和HIPAA)提供事件响应和修复来确保合规性

当然,像我一样,您可能仍然有问题:

  • “切换到EOL后支持版本到底有多容易?”
  • “我会获得在其他.NET版本中发现的安全问题的修复吗?”
  • “这将花费多少钱?”

最后一点将根据您的要求而有所不同,所以您需要自己深入研究。但我想了解前两个问题的技术方面,所以我尝试了HeroDevs的Never Ending Support(NES)for .NET 6!

尝试HeroDevs的Never Ending Support for .NET

HeroDevs为其Never-Ending Support(NES)for .NET提供对不受支持的.NET 6版本的直接替换。他们提供Linux和Windows二进制文件,因此无论您如何部署,都可以轻松修补现有应用程序。

我想测试NES二进制文件,我认为展示好处的最佳方法是针对最近的CVE-2025-55315漏洞测试二进制文件。

我的计划是:

  1. 使用最新的官方.NET 6版本创建一个简单的docker镜像
  2. 演示CVE-2025-55315漏洞的存在
  3. 更新docker镜像以使用HeroDevs的NES版本.NET 6
  4. 显示漏洞不再存在

幸运的是,正如我在关于CVE-2025-55315漏洞的文章中描述的那样,我们可以使用Hayden Barnes的GitHub repo测试.NET中漏洞的存在。

演示.NET 6易受CVE-2025-55315攻击

下面的dockerfile是我针对.NET 6测试的方式。它使用最新的.NET 10 SDK从复现GitHub repo构建应用程序,然后将发布的应用程序复制到最新的官方.NET 6 docker镜像中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# ---------------Builder image---------------------- #
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS builder

# Clone the reproduction repo
RUN git clone https://github.com/sirredbeard/CVE-2025-55315-repro /app

# Publish the app for .NET 6 to the /app/publish folder
RUN dotnet publish /app/Repro/Repro.csproj -c Release --framework net6.0 -o /app/publish

# ---------------Final image---------------------- #
# Use the latest official .NET 6 image
FROM mcr.microsoft.com/dotnet/aspnet:6.0

# Copy the published app from the builder image
WORKDIR /app
COPY --from=builder /app/publish .

# Run the app
ENTRYPOINT ["dotnet", "Repro.dll"]

请注意,我使用.NET 10构建了应用程序,但您始终可以使用更新版本的.NET SDK来构建针对旧版本.NET的应用程序。在许多方面,这比使用旧的.NET SDK更可取,因为您可以受益于编译器改进和使用更新版本的C#的能力。

要测试上述docker镜像,将其复制到名为Dockerfile的文件中,并使用以下命令构建和测试:

1
2
docker build -t andrewlock/repro-test:official-6.0 .
docker run --rm -it andrewlock/repro-test:official-6.0

这运行了与我们对.NET 8运行的相同漏洞复现测试,但这次测试失败,我们可以看到最新的.NET 6版本6.0.36易受CVE-2025-55315攻击,如日志中0/2测试通过所示:

这显示如果您今天运行.NET 6,您易受CVE-2025-55315攻击。

使用HeroDevs NES for .NET 6构建

要测试HeroDevs的NES for .NET 6支持,Hayden Barnes为我提供了一个包含他们修补的NES版本.NET 6的docker镜像。

这不一定是您需要将HeroDevs集成到构建管道中的方式,这只是对我来说方便的方法。HeroDevs提供多种集成方式,所以请联系他们获取更多细节!

我唯一做的更改是将"官方".NET 6镜像切换为HeroDevs修补的.NET 6版本。请注意,您不能按原样使用下面的docker镜像,您需要联系HeroDevs以获取修补的.NET版本;我直接由HeroDevs提供此镜像仅用于测试。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# ---------------Builder image---------------------- #
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS builder

RUN git clone https://github.com/sirredbeard/CVE-2025-55315-repro /app
RUN dotnet publish /app/Repro/Repro.csproj -c Release --framework net6.0 -o /app/publish

# ---------------Final image---------------------- #
#  👇 Using HeroDevs NES for .NET 6 version
FROM registry.nes.herodevs.com/oci/dotnet-runtime:6.0.39-bullseye-slim

WORKDIR /app
COPY --from=builder /app/publish .

ENTRYPOINT ["dotnet", "Repro.dll"]

然后我构建了docker镜像并使用以下命令运行它:

1
2
docker build -t andrewlock/repro-test:nes-6.0 .
docker run --rm -it andrewlock/repro-test:nes-6.0

从下面的日志中可以看到,NES版本的.NET 6不易受CVE-2025-55315攻击!🎉

上面的日志显示,NES for .NET构建中提供的.NET版本是6.0.39,高于最新的官方版本6.0.36。这要归功于HeroDevs在6.0.36基础之上应用于运行时和库的额外补丁。

就是这样。我们轻松地用HeroDevs的NES for .NET版本替换了易受攻击的.NET 6版本,我们的应用程序不再易受攻击。不需要昂贵或高风险的主要版本更新,只需支持您已经在使用的内容!

我没有严格演示的一个方面是我们甚至没有重新编译应用程序——我们只是交换了运行时镜像,而不是构建步骤。即使您无法重新构建应用程序(例如,也许您丢失了源代码),HeroDevs解决方案仍然有效,而更新到新的主要版本显然不是一个选择!

我在此示例中演示了一个ASP.NET Core应用程序,但HeroDevs支持许多不同的组件:.NET SDK、运行时、ASP.NET Core运行时、WPF等等!只需联系HeroDevs团队,看看他们如何帮助您保护应用程序。

结论

在本文中,我描述了微软为.NET提供的支持,包括"受支持"的含义、您每个月打补丁的要求,以及如果您不经常修补应用程序所暴露的风险。

然后我讨论了当主要版本不再受支持时保持最新的一些困难。主要版本更新可能意味着潜在耗时和昂贵的更新,具体取决于您需要支持的应用程序的数量和类型。

显然,更新到较新的主要版本有好处,我当然不是建议您不更新。但如果您不能更新,那么还有另一个选择:付费购买支持。

在许多其他生态系统中,为生命周期结束(EOL)产品付费购买支持是常见的。这只是一个被接受的维护成本,它使组织免于在框架EOL时必须更新所有应用程序的监管和维护障碍。

对于拥有数十、数百甚至数千个应用程序的组织来说,执行大规模迁移根本不切实际,而EOL后支持是一个非常实用的选择。

我认为.NET组织应该接受这一点。像HeroDevs这样的公司可以提供EOL运行时的修补版本,您可以"直接替换"到现有应用程序中,并获得即时支持和保护,您这边需要的工作非常少——您甚至不需要重新编译应用程序,这在某些情况下可能至关重要(哎呀,我们丢失了源代码😅)。

在本文结尾,我尝试了HeroDevs支持,展示了直接替换他们的Never Ending Support(NES)for .NET 6二进制文件是多么容易。切换到NES for .NET后,我演示了易受关键CVE-2025-55315漏洞攻击的应用程序现在如何受到保护。

更多组织应该考虑这条前进道路;如果升级到新的主要版本成本太高,或者根本不可能,请看看HeroDevs,看看他们是否能满足您的需求!

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计