Fix unsafe XML crypto snippets under System.Security.Cryptography.Xml - #13013
Fix unsafe XML crypto snippets under System.Security.Cryptography.Xml#13013krwq wants to merge 6 commits into
Conversation
Apply safe-by-default patterns to signing/verification and encryption samples: - Wrap XmlDocument.Load in XmlReader.Create so DTD processing is prohibited and no XmlResolver is used. - Replace parameterless SignedXml.CheckSignature() with the overload that takes a caller-provided trusted key. - For the CheckSignatureReturningKey sample, compare the returned key against a trusted key before accepting the signature.
There was a problem hiding this comment.
Pull request overview
This PR hardens the System.Security.Cryptography.Xml C# documentation snippets to be safer by default when loading XML and validating XML signatures, reducing the risk of XXE-style issues and “trust any key” signature-validation mistakes.
Changes:
- Updates many snippets to load XML via
XmlReaderinstead of directXmlDocument.Load(...). - Replaces parameterless
SignedXml.CheckSignature()with overloads that require a caller-provided trusted key. - Improves the
CheckSignatureReturningKeysample to validate that the returned signing key matches a trusted key.
Reviewed changes
Copilot reviewed 36 out of 36 changed files in this pull request and generated 38 comments.
Show a summary per file
| File | Description |
|---|---|
| snippets/csharp/System.Security.Cryptography.Xml/XmlDsigXsltTransform/Overview/sample.cs | Passes a trusted key into verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/XmlDsigXPathTransform/Overview/sample.cs | Passes a trusted key into verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/XmlDsigC14NWithCommentsTransform/Overview/sampleenvelope.cs | Passes a trusted key into verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/XmlDsigC14NWithCommentsTransform/Overview/sampledetached.cs | Passes a trusted key into detached-signature verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/X509IssuerSerial/Overview/sample.cs | Switches XML loading to XmlReader in signing/verification flow. |
| snippets/csharp/System.Security.Cryptography.Xml/SignedXml/XmlDsigExcC14NWithCommentsTransformUrl/sample.cs | Passes a trusted key into verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/SignedXml/XmlDsigExcC14NTransformUrl/example.cs | Passes a trusted key into verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/SignedXml/Overview/sample.cs | Adds trusted-key signature verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/SignedXml/Overview/exampleenvelope.cs | Switches XML loading to XmlReader in envelope signing/verification. |
| snippets/csharp/System.Security.Cryptography.Xml/SignedXml/CheckSignatureReturningKey/exampleenvelope.cs | Verifies signature then compares returned key to a trusted key; switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/SignedXml/CheckSignature/xmldsigenvkeyedhashalg.cs | Switches XML loading to XmlReader in keyed-hash signature example. |
| snippets/csharp/System.Security.Cryptography.Xml/SignedXml/CheckSignature/xmldsigdetachedkeyedhashalg.cs | Switches XML loading to XmlReader in detached keyed-hash signature example. |
| snippets/csharp/System.Security.Cryptography.Xml/SignedXml/CheckSignature/sample.cs | Switches XML loading to XmlReader in certificate-subject verification flow. |
| snippets/csharp/System.Security.Cryptography.Xml/SignedXml/CheckSignature/exampledetached.cs | Switches XML loading to XmlReader in detached signature verification flow. |
| snippets/csharp/System.Security.Cryptography.Xml/Signature/Overview/sample.cs | Passes a trusted key into verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/Reference/.ctor/sample.cs | Passes a trusted key into verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/KeyReference/Overview/sample.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/KeyInfoX509Data/Overview/examplecreateenvelope.cs | Switches XML loading to XmlReader during signing. |
| snippets/csharp/System.Security.Cryptography.Xml/KeyInfoX509Data/.ctor/sample.cs | Switches XML loading to XmlReader in signing/verification flow. |
| snippets/csharp/System.Security.Cryptography.Xml/KeyInfo/Overview/xmldsigenv.cs | Passes a trusted key into verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/KeyInfo/Overview/xmldsigdetach.cs | Passes a trusted key into detached-signature verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/IRelDecryptor/Overview/sample.cs | Requires a trusted key for signature checking and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/EncryptionProperty/Overview/sample.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/EncryptedXml/Overview/sample4.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/EncryptedXml/Overview/sample3.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/EncryptedXml/Overview/sample2.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/EncryptedXml/Overview/sample1.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/EncryptedXml/Overview/sample.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/EncryptedXml/AddKeyNameMapping/sample.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/EncryptedType/Overview/sample.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/EncryptedKey/Overview/example.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/EncryptedData/Overview/sample.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/DSAKeyValue/Overview/exampleenvelope.cs | Passes a trusted key into verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/DSAKeyValue/Overview/exampledetached.cs | Passes a trusted key into detached-signature verification and switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/DataReference/Overview/sample.cs | Switches XML loading to XmlReader. |
| snippets/csharp/System.Security.Cryptography.Xml/DataObject/Overview/source1.cs | Introduces trusted-key signature verification and switches XML loading to XmlReader. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
The comments by Copilot about passing an XmlReaderSettings isn't needed now. It used to be needed as the default behavior on .NET Framework was target framework version dependent. If you had an app targeting .NET 4.5, the default behavior was to do DTD processing and provide a default implementation of the XmlResolver which would download referenced/included files. Because you might not know which target framework version your code would be running against, if it was library code, then it's safest to be explicit. All currently supported versions of .NET Framework and .NET have safe defaults so it's not needed. It's only if someone is still targeting an out of support version of .NET Framework, or explicitly opted in to the unsafe behavior that this would be a concern. |
The AsymmetricAlgorithm instance returned via the out parameter is owned by the caller and can hold native crypto handles. Wrap it in a using block so it is disposed on every path, including the verification-failed and non-RSA fallbacks.
Snippets5000 now compiles this file as part of the PR change set. It has no sibling Project.csproj, so Snippets5000 falls back to an auto-generated project without a reference to the System.Security.Cryptography.Xml assembly, and the pre-existing use of an unassigned X509IssuerSerial local both broke the build. Add a peer-shaped Project.csproj (net10.0-windows, UseWindowsForms) matching the other samples in this tree, and initialize the xserial struct with default so it is definitely assigned before its fields are set.
|
I had to add project file because Snippets 5000 apparently runs only on changed files and this project file was missing but since we didn't touch it earlier we didn't see the error |
… (VB) Port the same safe-by-default patterns already applied to the C# samples to their Visual Basic counterparts: - Wrap XmlDocument.Load in XmlReader.Create so DTD processing is prohibited and no XmlResolver is used. - Replace parameterless SignedXml.CheckSignature() with the overload that takes a caller-provided trusted key. - For the CheckSignatureReturningKey sample, compare the returned key against a trusted key before accepting the signature and dispose the returned AsymmetricAlgorithm.
|
I ended up changing also VB snippets here |
…ions The changed samples in EncryptedXml/Overview, SignedXml/CheckSignature, and SignedXml/Overview (C# and VB) live alongside sibling files that declare the same top-level Class/Module name (Program, SignVerifyEnvelope, XMLDSIGDetached). Compiling them together produces CS0101/CS0111/BC30179 errors. Add per-folder Project.csproj/vbproj that build a single representative sample by using EnableDefaultCompileItems=false plus an explicit Compile Include. This satisfies Snippets5000 discovery for every changed file in the folder without introducing class-name conflicts and without editing any sample source. Each sample still compiles standalone; the CI coverage matches the pre-PR state for these folders (no project ever existed there).
Apply safe-by-default patterns to signing/verification and encryption samples:
Internal previews
Toggle expand/collapse
Note
This table shows the first 30 preview links (sorted alphabetically by file path) found in the OPS build report. For the full list, select OpenPublishing.Build Details within checks.