Puede haber un problema en muchas aplicaciones basadas en la verificación de firmas XML (siempre que no me equivoque, por supuesto).
Tengamos un mensaje XML simple con una firma XML envuelta:
<?xml version="1.0" encoding="UTF-8"?>
<message>
<msgenvelope id="SIGNED_DATA">some signed data</msgenvelope>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
...
<Reference URI="#SIGNED_DATA">
...
</Reference>
</SignedInfo>
<SignatureValue>naUY...+xZbEA=</SignatureValue>
</Signature>
</message>
De acuerdo con este MSDN , debes verificar un documento XML de este tipo con la clase SignedXml
:
SignedXml signedXml = new SignedXml(Doc); //Doc is my message
XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
signedXml.LoadXml((XmlElement)nodeList[0]);
bool ok = signedXml.CheckSignature(Key);
if (ok) {
string signedData = Doc.SelectSingleNode("/message/msgenvelope").InnerText;
//do something with the signed data
} else {
//throw error or something
}
Creo que hay un problema: el método CheckSignature
verifica si el valor de la firma es correcto, pero no si los datos firmados son realmente los datos que se espera que se firmen.
Un tipo malvado podría modificar el mensaje de esta manera:
<?xml version="1.0" encoding="UTF-8"?>
<message>
<msgenvelope id="anotherid">FAKE DATA!!</msgenvelope>
<evil_envelope>
<msgenvelope id="SIGNED_DATA">some signed data</msgenvelope>
</evil_envelope>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
...
<Reference URI="#SIGNED_DATA">
...
</Reference>
</SignedInfo>
<SignatureValue>naUY...+xZbEA=</SignatureValue>
</Signature>
</message>
Este mensaje se verifica correctamente, porque el elemento firmado y la firma siguen siendo los mismos. Sin embargo, la cadena de datos resultante contiene "FAKE DATA !!".
Hay varias maneras de evitar este ataque: usar la verificación de esquema contra XSD, verificar el atributo id
del elemento confiable, etc. ¿Cuál es el enfoque recomendado para deshacerse de este riesgo? ¿Debería mejorarse el artículo de MSDN? ¿Hay alguna implementación de referencia que maneje este problema correctamente?