目录
System.Net.Http和System.Text.RegularExpressions
介绍
2023年11月(NuGet 6.8、Visual Studio 17.8、.NET SDK 8.0.100)我们发布了NuGet审核。当项目使用具有已知漏洞的包时,NuGet Audit会在还原期间提供警告。有关NuGet Audit的更多信息,包括详细的配置选项,请访问我们的学习网站。新功能仍在添加中,因此如果您最近没有阅读文档,请考虑再看一遍,或查看我们的发行说明,看看是否添加了可能对您有帮助的新功能。
以下是NuGet 6.12、Visual Studio 17.12、.NET SDK 9.0.100中将提供的可用设置的快速摘要。
设置 | 描述 |
NuGetAudit(属性) | 启用或禁用NuGetAudit |
NuGetAuditMode(属性) | 仅报告具有已知漏洞的直接包,或同时报告具有已知漏洞的目录包和传递包。 |
NuGetAuditSeverity (属性) | 选择要报告的最低漏洞严重性。 |
NuGetAuditSuppress (项) | 不要警告特定的咨询URL。 |
WarningsNotAsErrors (属性) | 这不是特定于NuGet审核的,但如果您的项目使用TreatWarningsAsErrors,请考虑将NU1901、NU1902、NU1903和NU1904添加到此列表中,以避免新披露的包漏洞导致还原和生成失败。 |
auditSources (nuget.config) | 如果未提供审核源,NuGet将使用包源下载漏洞数据库以用于审核。NuGet.config的auditSources将允许您使用nuget.org(或其他源的)漏洞数据库,而无需将其作为包源。 |
.NET 9和VS 17.12中NuGet审核的一个重大变化是NuGetAuditMode默认值已从“直接”更改为“全部”。使用TreatWarningsAsErrors的项目可能会看到新的错误。可以使用WarningsNotAsErrors将NuGet Audit的警告视为警告。使用Directory.Build.props文件可用于在所有子目录中包含的所有项目中自动设置它。
它是什么样子的
在命令行还原时,NuGet审核的警告将像任何其他MSBuild警告或错误一样显示:
D:\src\test\vulnTest\ClassLib1\ClassLib1.csproj:警告NU1903:程序包“Newtonsoft.Json”9.0.1存在已知的高严重性漏洞,https://github.com/advisories/GHSA-5crp-9r3c-p9vr [D:\src\test\vulnTest\vulnTest.sln]
在Visual Studio中,这些警告将显示在Error List(错误列表)窗口中
解决方案资源管理器将显示一个黄色条,警告您至少有一个项目具有具有已知漏洞的包。有一个可单击的链接,可将您带到解决方案的NuGet包管理器UI(PM UI)。注意:目前,解决方案级别的PM UI不显示传递包,只显示直接包。
此外,使用较新SDK样式项目的项目将在项目下具有Dependencies节点,并且与特定包相关的任何警告都显示在包本身下。使用较旧的非SDK样式格式的项目将具有references节点,而不是依赖项,并且不会显示有关包特定警告的其他信息,也不会显示覆盖图标。
解决警告的推荐方法
收到有关具有已知漏洞的软件包的警告只是该过程的一部分。一旦发现,就需要采取措施从您的解决方案中消除潜在漏洞。
最简单的情况是,当您直接引用的软件包具有已知漏洞时,在这种情况下,您将版本更新为另一个版本来修复该漏洞。如果不存在更新的版本,您可以尝试联系软件包所有者,但您可能需要寻找替代软件包并停止使用具有已知漏洞的软件包。有关修复的更多提示,请参阅我们关于审核包依赖项的文档
但是,漏洞通常位于传递依赖项中,并且解决方案并不那么明显。我们的建议是首选 “最接近” 直接引用的软件包的更新。不过,仅升级具有已知漏洞的软件包也没有错。
例如,假设您的项目引用了包A。包A依赖于包B,而包B又依赖于包C。在此示例中,我们将考虑软件包C版本1.0.0存在已知漏洞,该漏洞已在版本2.0.0中修复。我们建议首先尝试升级包A。如果这没有解决审核警告,请尝试升级软件包B。如果这没有解决审计警告,则直接升级C。
如何升级传递包
为了将可传递包升级到更高版本,您需要将其添加为直接包引用。我们的文档提供了有关NuGet依赖项解析算法的更多信息。
通过将中央包管理与传递固定设置结合使用,CPM可以为您自动执行此操作,还有一个额外的好处,即当您升级直接包引用并且不再需要传递包时,它会自动从项目的包图中消失。但是,请注意,如果您将项目打包到自己的包中以与他人共享,则具有传递固定的CPM仍会导致包成为依赖项,即使您的项目不直接调用该包上的API。
禁止显示特定公告
有时,您可能会在安全审核后确定您的软件没有面临特定公告的足够风险。例如,过去的几个序列化库都有安全建议,当攻击者可以构建具有深层对象嵌套的输入时,存在拒绝服务(DoS)风险,从而导致堆栈溢出。通常,可以通过告诉序列化程序限制允许的最大嵌套深度来缓解这种情况。因此,如果您的软件已经缓解了软件包的安全风险,则可以选择禁止显示特定公告。
为此,请使用文本或XML编辑器编辑项目文件,并在ItemGroup中添加NuGetAuditSuppress元素。
<Project Sdk="Microsoft.NET.Sdk">
<!-- other parts of the project left out of this example -->
<ItemGroup>
<NuGetAuditSuppress Include="https://github.com/advisories/GHSA-6qmf-mmc7-6c2p" />
</ItemGroup>
</Project>
如果您希望在一个位置定义这些MSBuild项,但将其应用于子目录中的所有项目,则可以将这些MSBuild项放在Directory.Build.props文件中。但是,您可能还希望考虑仅将其放在已执行安全审查的特定项目中,以最大程度地降低解决方案中的其他项目采用相同依赖项并开始以不安全的方式使用库的风险。
但是,我们强烈建议您将程序包升级到没有已知漏洞的版本,而不是禁止显示公告。
如何查找可传递包路径
有几种方法可以查找包路径。您更喜欢哪种方法取决于您在开发过程中通常使用的工具。
dotnet nuget why
在命令行中,dotnet nuget why已添加到.NET SDK 8.0.400和.NET 9预览版6 SDK。向其传递项目文件和包ID,它将显示包为何位于包图中,即使通过项目引用也是如此。
与dotnet CLI的其余部分一样,它直接仅支持SDK样式的项目。如果你的Visual Studio项目不能使用.NET SDK,则可以使用Visual Studio或MSBuild还原项目。NuGet在项目的obj/目录(技术上的,使用MSBuild MSBuildProjectExtensionsPath属性)中创建一个名为project.assets.json的文件。使用最新版本的VS 2022,您还可以使用msbuild -getProperty:ProjectAssetsFile查找assets文件的路径。最后,从.NET 9预览版7 SDK开始,您将能够传递dotnet nuget why assets文件作为项目文件的替代品。例如dotnet nuget why path\to\project.assets.json System.Text.RegularExpressions。
VS解决方案资源管理器
SDK样式项目还在项目的Dependency节点下提供完整的包图。它也是可搜索的!
首先,展开搜索选项并启用“搜索外部文件”。
然后,您可以搜索包名称,它将显示每个项目的Dependencies节点下的所有实例。
Visual Studio NuGet包管理器UI
当您查看Visual Studio的包管理器UI中的Installed选项卡时,当项目使用PackageReference包管理时,它将同时显示直接包和传递包。目前,这仅在您管理项目的包时发生,而不是在管理解决方案的包时发生,尽管我们正在努力改进这一点。
如果将鼠标悬停在包列表中的包上,则工具提示将包含一个直接包的名称,该包导致该传递包包含在项目中。
手动查看资产文件
上述所有体验都基于读取NuGet的资产文件,因此,如果它们都不起作用,则始终可以直接查看资产文件以查找相同的信息。assets文件不应被视为稳定的格式,因此我们不建议构建读取该文件的工具。我们已经有即将推出的功能计划,这些计划需要在json架构中引入重大更改,但我们将更改文件顶部的版本号。但是,在手动查看和搜索文件时,这不是问题。
通常,可以在项目目录下的obj/project.assets.json中找到assets文件,但如果您使用.NET SDK的工件输出布局,或者以其他方式更改默认布局,您也可以通过在命令提示符上运行以下命令来查找位置:
dotnet msbuild -getProperty:ProjectAssetsFile
如果您的项目是非SDK样式的,则可能会收到有关找不到导入的错误。在这种情况下,请打开Visual Studio的开发人员命令提示符,并从命令行中删除dotnet,以直接使用Visual Studio的MSBuild.exe命令。
使用文本编辑器搜索具有已知漏洞的软件包ID,浏览可能的多个搜索结果,您将能够找到哪些软件包将该软件包列为依赖项。对其他包重复此操作,直到找到要查找的信息,可能是项目直接引用的包。以下示例显示Newtonsoft.Json和其他一些包是NuGet.Packaging包的依赖项:
"NuGet.Packaging/5.11.3": {
"type": "package",
"dependencies": {
"Newtonsoft.Json": "9.0.1",
"NuGet.Configuration": "5.11.3",
"NuGet.Versioning": "5.11.3",
"System.Security.Cryptography.Cng": "5.0.0",
"System.Security.Cryptography.Pkcs": "5.0.0"
},
特定软件包的注意事项
System.Net.Http和System.Text.RegularExpressions
这些包来自.NET Core 1.x,自.NET Core 2.0起变得冗余。由于所有受支持的.NET平台也支持.NET Standard 2.0,因此我们不建议使用低于2.0的.NET Standard版本。如果项目直接引用这些包(或任何其他System.*包版本4.*),则可以删除包引用,因为程序集内置于目标框架的引用程序集中。如果您的项目以传递方式获取这些包,请遵循我们之前的指南,选择升级更靠近您的项目的包。希望有更新版本的包不再使用.NET Standard 1.x或这些包。
运行时包
如果您查看一些.NET平台的安全建议,例如GHSA-hhc7-x9w4-cw47或GHSA-7fcr-8qw6-92fr,您可以看到受影响的程序包都以Microsoft.NetCore.App.Runtime.*或Microsoft.AspNetCore.App.Runtime.*开头。这些包不是由项目直接引用的,而是由.NET SDK本身隐式添加的。若要停止使用这些包的易受攻击版本,必须升级到较新版本的.NET SDK。
即将推出的改进
改善检测和管理具有已知漏洞的软件包的体验的工作并没有停止。以下是我们正在开发的一些即将推出的功能。您可以在我们的GitHub问题中搜索带有NuGetAudit标记的问题,以查看现有想法和bug报告。如果您有一个想法,但找不到要投票的现有问题,您可以在那里创建一个新的功能请求。
PM UI改进
目前,Visual Studio的NuGet包管理器UI仅显示可传递包,这些包是项目直接引用的包的依赖项。但它不显示仅通过项目引用传入的包。这将被改变。
此外,当您将鼠标悬停在可传递包上时,它会显示哪个直接包引用导致可传递包包含在项目中。如果一个传递包由多个顶级包引入,则只会报告其中一个顶级包。我们将对此进行改进,以便提供更多信息,因为非SDK样式的项目没有SDK样式项目所具有的Solution Explorer视图。
由平台提供
NuGet和.NET SDK团队正在开发一个名为“由平台提供”的功能,该功能将允许.NET SDK通知NuGet哪些包现在是.NET引用程序集的一部分。这将允许NuGet自动从还原图中剔除这些包。这意味着,不仅System.Net.Http和System.Text.RegularExpressions等包会自动删除并防止NuGet审核警告,而且还原性能也会提高,因为任何将NETStandard.Library列为依赖项的包(通常为1.6.1版)都将从图中删除数十个包,这意味着要下载和递归检查其自身依赖项的包更少。
dotnet nuget审核修复
我们还希望提供一种方法,通过运行单个命令来自动解决项目的所有已知漏洞。它将实施上述推荐的方法,分析软件包图并测试升级,找出哪种升级组合会删除所有具有已知漏洞的软件包。与任何自动化工具一样,它并不适合所有场景。例如,如果具有已知漏洞的包仅在具有重大更改的包版本中具有修复程序,则解决已知漏洞的修复程序可能会使您的项目无法构建。但我们相信,对于大多数开发人员来说,这将是一个良好且快速的解决方案。
警告和错误从Visual Studio的错误列表中消失
我们注意到一个问题,即非SDK样式的项目(Visual Studio的新项目向导称它们为“.NET Framework”项目)在一次或两次生成后,NuGet警告会从错误列表中消失。我们正在调查清除错误列表的原因,以及NuGet需要执行哪些操作来保留其警告。命令行restore(msbuild -t:restore)将始终显示警告,直到此问题得到解决。
总结
我们介绍了NuGet审核即将进行的更改,详细介绍了如何识别和解决NuGet包中的漏洞。您学习了如何设置严重性级别、禁止显示特定公告以及使用新工具来管理漏洞和维护安全性。请继续关注未来的增强功能,以简化漏洞管理,并确保查看文档以获取最新信息。