Is this a weakness of enveloped XML signature?

To me, this seems not really as a error of the protocol but as wrongly used.

You get a part of the XML using Doc.SelectSingleNode("/message/msgenvelope") but you never checked that "/message/msgenvelope" is actually the signed part of the XML!

You have to treat the XML more like a file system with different files and not like one entity. Think like this: you have three files: a.exe, b.exe and secure.signature You check secure.signature and it tells you: File a.exe was signed by Trusted Guy and is not changed. If you then execute b.exe and think this is secure, it's not a security problem of the signature.

This is basically what you do in the example! You ask if the Signature is valid and get back that it is valid. But it also states <Reference URI="#SIGNED_DATA"> which means that the signature is valid exactly for #SIGNED_DATA and nothing else.

You then ask to get the part identified by /message/msgenvelope and treat it like it has a valid signature!

But /message/msgenvelope is clearly not the same as #SIGNED_DATA. It might identify the same element, it might not. But you most certainly never checked the signature of /message/msgenvelope explicitly!


As already stated, this is that way by design. Probably MSDN article could (or should) be more explicit about that. The way you extracted the "signed" data is wrong. The XMLDSig documentation is clear about it. You may want to read section 8.1 of this link https://www.w3.org/TR/xmldsig-core/

Just as a user should only sign what he or she "sees," persons and automated mechanism that trust the validity of a transformed document on the basis of a valid signature should operate over the data that was transformed (including canonicalization) and signed, not the original pre-transformed data.

and

Note that the use of Canonical XML [XML-C14N] ensures that all internal entities and XML namespaces are expanded within the content being signed. All entities are replaced with their definitions and the canonical form explicitly represents the namespace that an element would otherwise inherit. Applications that do not canonicalize XML content (especially the SignedInfo element) SHOULD NOT use internal entities and SHOULD represent the namespace explicitly within the content being signed since they can not rely upon canonicalization to do this for them. Also, users concerned with the integrity of the element type definitions associated with the XML instance being signed may wish to sign those definitions as well (i.e., the schema, DTD, or natural language description associated with the namespace/identifier).

Second, an envelope containing signed information is not secured by the signature. For instance, when an encrypted envelope contains a signature, the signature does not protect the authenticity or integrity of unsigned envelope headers nor its ciphertext form, it only secures the plaintext actually signed.

More details on how to correctly validate a signature are found here: https://www.w3.org/TR/xmldsig-core/#sec-CoreValidation

The input to the first Transform is the result of dereferencing the URI attribute of the Reference element.

One should only trust on the result of dereferencing References from SignerInfo. All other data should not be considered signed and should not be presented to the user.

PS: Yes, XMLDSig is very complex. And implementations can easily get it wrong.