Potrebbe esserci un problema in molte applicazioni basate sulla verifica della firma XML (a condizione che non sbagli, ovviamente).
Abbiamo un semplice messaggio XML con una firma XML con involucro:
<?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>
In base a questo articolo MSDN , devi verificare tale documento XML con la classe 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
}
Penso che ci sia un problema: il metodo CheckSignature
verifica se il valore della firma è corretto, ma non se i dati firmati sono realmente i dati che dovrebbero essere firmati.
Un malvagio potrebbe modificare il messaggio in questo modo:
<?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>
Questo messaggio è stato verificato correttamente, perché l'elemento firmato e la firma sono sempre gli stessi. Tuttavia, la stringa di dati risultante contiene "FAKE DATA !!".
Ci sono alcuni modi per evitare questo attacco - usando la verifica dello schema contro XSD, controllando l'attributo id
dell'elemento fidato ecc. Qual è l'approccio raccomandato per eliminare questo rischio? L'articolo MSDN dovrebbe essere migliorato? Esiste un'implementazione di riferimento che gestisca correttamente questo problema?