自MS14-059以来,System.Web.MVC未复制到bin文件夹中.如何防止因Windows更新而导致缺少DLL的构建?

Dan*_*eny 36 .net windows asp.net security asp.net-mvc

今天早上据报道,我们的QA服务器上的网络应用程序完全被破坏,并报告了来自Web.config的以下错误:

无法加载文件或程序集'System.Web.Mvc,Version = 5.1.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35'或其依赖项之一.该系统找不到指定的文件

记住眼看提到MVC一个Windows更新,我做了一些挖掘和发现大量 报告最近的Windows更新打破MVC.

在仔细研究了这些问题和我们的服务器之后,似乎被咬过的东西与那些其他问题中的东西不匹配,但它看起来确实相关.这是我们认为的知识:

  • 我们破解的应用程序使用ASP.NET MVC 5.1
  • MVC是通过NuGet安装的
  • 我们的BuildServer和QA服务器没有安装MVC 5.1(因此,不是GAC)

我们认为已经破坏的原因导致了"糟糕的构建":

  • 尽管没有在GAC中安装MVC 5.1,但是通过Windows Update在BuildServer上安装了MVC 5.1补丁
  • 该补丁已将"更新"版本的MVC 5.1置于GAC中
  • 当DLL在GAC中时,将忽略CopyLocal = true; 因此,自补丁以来,这意味着我们从BuildServer构建的应用程序不再在输出文件夹中有System.Web.MVC
  • 由于System.Web.MVC不在我们的QA服务器上的GAC中(它们尚未修补),因此应用程序现在失败,因为找不到System.Web.MVC

假设上述行为是正确的,这意味着任何时候MS通过Windows Update 在GAC中为NuGet DLL提供服务,我们的BuildServer将开始生成不完整的构建(错过那些已经注入GAC的DLL) .

升级到MVC 5.2解决了这个问题(可能是因为它没有修补,因此没有注入GAC); DLL现在已复制到输出文件夹.除了版本号更改(特别是没有<Private>添加/编辑节点)之外,差异没有变化升级到5.2.2 .

我们不希望开始GACing所有内容,也不希望创建手动构建步骤将所有DLL复制到bin文件夹中,以防MS修补它们.

那么,今天我们可以改变什么来确保我们不会最终导致BuildServer默默地产生错误的构建,如果MS将来修补其他DLL?

dma*_*son 14

尽管没有在GAC中安装MVC 5.1,但是通过Windows Update在BuildServer上安装了MVC 5.1补丁

是的,这种行为实际上是设计的.请参阅http://blogs.msdn.com/b/dotnet/archive/2014/01/22/net-4-5-1-supports-microsoft-security-updates-for-net-nuget-libraries.aspx.


该补丁已将"更新"版本的MVC 5.1置于GAC中

对,那是正确的; 这是补丁如何获取更新的代码而不是旧代码.请参阅https://technet.microsoft.com/en-us/library/security/ms14-059.


当DLL在GAC中时,将忽略CopyLocal = true; 因此,自补丁以来,这意味着我们从BuildServer构建的应用程序不再在输出文件夹中有System.Web.MVC

不完全是.实际发生的是以前是CopyLocal = true的项目切换到CopyLocal = false.CopyLocal可以通过以下两种方式之一进行设置:1)如果<Private>True</Private>.csproj文件中有显式设置,或者2)默认情况下,如果不存在此类设置(默认情况下GAC程序集不会复制CopyLocal;其他程序集会执行此操作).

所以在这种情况下似乎发生的事情是你的项目文件在csproj文件中没有这个设置.因此,GUI在补丁之前显示了基于评估的默认值的设置(CopyLocal = true),但是在安装补丁之后,GUI现在将显示GAC程序集的新默认值(CopyLocal = false) ).


由于System.Web.MVC不在我们的QA服务器上的GAC中(它们尚未修补),因此应用程序现在失败,因为找不到System.Web.MVC

那是对的.


假设上述行为是正确的,这意味着任何时候MS通过Windows Update在GAC中为NuGet DLL提供服务,我们的BuildServer将开始生成不完整的构建(错过那些已经注入GAC的DLL) .

对于没有显式<Private>True</Private>设置的任何.csproj引用,这是正确的.此外,请注意使用NuGet更新MVC引用可以删除此设置,即使它以前存在.请参见http://nuget.codeplex.com/workitem/4344.


升级到MVC 5.2解决了这个问题(可能是因为它没有修补,因此没有注入GAC); DLL现在已复制到输出文件夹.除了版本号更改(特别是没有添加/编辑节点)之外,差异没有变化升级到5.2.2.

那是对的.由于MVC 5.2不是GAC,即使没有明确的<Private>True</Private>设置,这个非GAC程序集的默认值将是CopyLocal = true.


我们不希望开始GACing所有内容,也不希望创建手动构建步骤来将所有DLL复制到bin文件夹中,以防MS修补它们.那么,今天我们可以改变什么来确保我们不会最终导致BuildServer默默地产生错误的构建,如果MS将来修补其他DLL?

你今天能做的最好的事情是:

  1. <Private>True</Private>在.csproj文件中为所有NuGet包程序集引用添加显式设置.
  2. 在NuGet错误#4344修复之前,只要您使用NuGet更新包引用,请返回到.csproj文件并重新添加显式<Private>True</Private>设置.


Jam*_*s S 5

我相信这个问题在.Net Web开发工具和UI博客中得到解决:链接

我不会重复这里的全部内容,因为在该链接上可以很好地解释问题和解决方案.

然而,只是重复关键点,这应该解释为什么会发生这种情况:

  • 作为补丁KB2994397的一部分,MVC 5.1已添加到GAC中.

  • 似乎有一个重置CopyLocal标志的NuGet错误.(参见链接)这意味着当具有上述补丁的机器部署到未修补的机器时,它将会中断!

  • MVC 4的组件版本号增加了相同的安全更新 - MS14-059(因此不会使用GAC版本)这解释了为什么MVC 4版本仍然有效 - 尽管它在GAC中.