Today we released MS10-041 addressing an issue in the implementation of the XML signature functionality in the .NET Framework with an Important severity rating.  We’d like to shed more light on that case here.


Am I at risk?


No Microsoft products are subject to this vulnerability.  However, .NET applications that use the System.Security.Cryptography.Xml.SignedXml.CheckSignature(KeyedHashAlgorithm macAlg) method are susceptible.  Note that only the CheckSignature() method that takes a KeyedHashAlgorithm parameter is affected – the other CheckSignature() methods are not.


Anyone running applications that call this method should install this update as soon as possible. The update protects against the vulnerability without the need to recompile these applications.


If you allow updates to install automatically, there’s nothing else you have to do.  Once the update has been installed, your applications will be safe from this vulnerability.  In addition, after extensive evaluation we’ve assigned this vulnerability an overall Exploitability Index rating of 3, meaning that we believe that functioning exploit code is unlikely in the near future.


What could an attacker do?


As the bulletin explains, this vulnerability could make it possible for an attacker to modify XML signature protected data without being detected.  The impact of the tampering depends on how the affected data is intended to be used by the specific application, but is unlikely to result in arbitrary code execution.


Background information


One of the features of an XML signature is the ability to embed a value, called the HMACOutputLength, in the signature that tells the receiver how many bits of the signature to examine.  However, the specification did not require that implementations of the specification enforce a minimum value for this field.


In the .NET implementation, as well as other implementations by other vendors, no minimum HMACOutputLength value was enforced, so a man-in-the-middle attacker could set this value to 0 and then tamper with the contents of the XML without detection.


The updated specification now says that implementations must validate that HMACOutputLength is >= MAX(80, HalfOfTheBitsTheSignatureMethodGenerates).


XML signatures are defined by the W3C in this document:


How to determine if you have any affected applications on your computer


The .NET Framework SDK comes with a disassembly tool which can extract the IL code from a .NET binary.  The following PowerShell script calls this tool for every .EXE and .DLL file under the folder you execute the script in, and examines the output of the tool to tell you if any of the binaries call the vulnerable function.  To run this PowerShell script, you’ll need to install PowerShell if you’re not using Windows 7 (PowerShell comes with Windows 7), and you’ll need to install the .NET Framework SDK or Visual Studio, and finally update the first line of the script to point to the location that ildasm.exe was installed on your computer.


$PathToILDASM = "C:\Program Files\Microsoft.NET\SDK\2.0\Bin"

$FilesToScan = get-childitem -Filter *.exe -Recurse
$FilesToScan += get-childitem -Filter *.dll -Recurse

"Found " + $FilesToScan.Count + " EXE and DLL file(s) to scan"
"Binaries that contain calls to System.Security.Cryptography.Xml.SignedXml.CheckSignature(KeyedHashAlgorithm macAlg):"

foreach($File in $FilesToScan)
    $FileName = $File.FullName
    if (([string]$FileName).Length -gt 0)
        $Process = New-Object -typeName System.Diagnostics.Process
        $Process.StartInfo.WorkingDirectory = (get-location).Path
        $Process.StartInfo.UseShellExecute = $false
        $Process.StartInfo.RedirectStandardOutput = $true
        $Process.StartInfo.RedirectStandardError = $true
        $Process.StartInfo.FileName = [System.IO.Path]::Combine($PathToILDASM, "ildasm.exe")
        $Process.StartInfo.Arguments = "/OUT=temp.txt `"$FileName`" /NOBAR"
        $Process.Start() | out-null
        if (Test-Path temp.txt)
            $Disassembly = Get-Content temp.txt
            del temp.txt
            if (([string]$Disassembly).Contains("callvirt   instance bool [System.Security]System.Security.Cryptography.Xml.SignedXml::CheckSignature(class [mscorlib]System.Security.Cryptography.KeyedHashAlgorithm)"))


Thanks to Shawn Farkas, Damian Hasse, Joe Hemmerlein, Alex Lucas, and Andrew Roths for their help with this blog post!

-Kevin Brown, MSRC Engineering