Description
EncryptedXml throws NullReferenceException instead of CryptographicException when parsing an encrypted XML document whose KeyInfo/RetrievalMethod (or CipherData/CipherReference) element omits the URI attribute.
The root cause is three call sites in EncryptedXml.cs that pass a nullable Uri property into Utils.ExtractIdFromLocalUri without a null check (two of them use the null-forgiving ! operator), and Utils.ExtractIdFromLocalUri itself dereferences its parameter with uri!.Substring(1).
This means any caller that runs EncryptedXml.DecryptDocument() over untrusted input needs to catch NullReferenceException — which is not an exception type consumers of a cryptography API should be expected to handle.
Reproduction Steps
<root><EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#"><KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><RetrievalMethod/></KeyInfo><CipherData><CipherValue>AA==</CipherValue></CipherData></EncryptedData></root>
var doc = new XmlDocument { XmlResolver = null };
doc.LoadXml(File.ReadAllText(path));
new EncryptedXml(doc).DecryptDocument();
Stack:
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Security.Cryptography.Xml.Utils.ExtractIdFromLocalUri(String uri)
at System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, String symmetricAlgorithmUri)
at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument()
Expected behavior
When the library needs to dereference a URI that is missing or empty (regardless of whether the attribute is schema-required, as on CipherReference, or schema-optional, as on RetrievalMethod), it should throw CryptographicException — matching the rest of the library's input-validation errors, and matching what CipherReference.LoadXml already does today.
Actual behavior
NullReferenceException propagates out of DecryptDocument().
Regression?
No. Reproduced on version 8.0.3 and 9.0.15 of the package.
Known Workarounds
Callers of EncryptedXml.DecryptDocument() on untrusted input need to wrap the call in try { ... } catch (NullReferenceException) { ... }.
Configuration
- .NET version: reproduces on both the .NET 10 host and the .NET 11 preview host; the behavior is determined by the
System.Security.Cryptography.Xml package version
- OS: Linux (Ubuntu 22.04, running under WSL2 on Windows); not OS-specific - the affected code path is fully managed IL
- Architecture: x64
- Configuration-specific? No. Managed-only code, no native interop on this path.
Other information
Found via fuzzing with SharpFuzz + AFL++ against System.Security.Cryptography.Xml 10.0.6.
Description
EncryptedXmlthrowsNullReferenceExceptioninstead ofCryptographicExceptionwhen parsing an encrypted XML document whoseKeyInfo/RetrievalMethod(orCipherData/CipherReference) element omits theURIattribute.The root cause is three call sites in
EncryptedXml.csthat pass a nullableUriproperty intoUtils.ExtractIdFromLocalUriwithout a null check (two of them use the null-forgiving!operator), andUtils.ExtractIdFromLocalUriitself dereferences its parameter withuri!.Substring(1).This means any caller that runs
EncryptedXml.DecryptDocument()over untrusted input needs to catchNullReferenceException— which is not an exception type consumers of a cryptography API should be expected to handle.Reproduction Steps
Stack:
Expected behavior
When the library needs to dereference a
URIthat is missing or empty (regardless of whether the attribute is schema-required, as onCipherReference, or schema-optional, as onRetrievalMethod), it should throwCryptographicException— matching the rest of the library's input-validation errors, and matching whatCipherReference.LoadXmlalready does today.Actual behavior
NullReferenceExceptionpropagates out ofDecryptDocument().Regression?
No. Reproduced on version 8.0.3 and 9.0.15 of the package.
Known Workarounds
Callers of
EncryptedXml.DecryptDocument()on untrusted input need to wrap the call intry { ... } catch (NullReferenceException) { ... }.Configuration
System.Security.Cryptography.Xmlpackage versionOther information
Found via fuzzing with SharpFuzz + AFL++ against
System.Security.Cryptography.Xml10.0.6.