- From: Pratik Datta <pratik.datta@oracle.com>
- Date: Thu, 29 May 2008 16:06:34 -0700
- To: Sean Mullan <Sean.Mullan@sun.com>
- CC: XMLSec <public-xmlsec-maintwg@w3.org>
Sean, Here are my proposed edits to make things clearer. (It doesn't include any reorganization, we could discuss that in the call) -------------------------------------- Section 2.1 Complexity is the enemy of security [BradHill] <#ref-BradHill>. Avoid using complicated features of XML Signature, especially complicated transforms, since it makes it hard for the receiver to know what was actually signed Consider the following XML where the Approval needs to be signed <Doc> <Approval>...</Approval> </Doc> The receiver needs to verify that a) the Approval element was signed, b) signing key is valid, and c) the signature itself is valid. It is not very easy to verify that the Approval element is signed. Let us say the convention is to have a disjoint signature that refers to the Approval element by id e.g. this is what the receiver is expecting -- Example 1--- <Doc> <Approval xml:id="ap">...</Approval> <Signature> ... <Reference URI="ap"/> ... </Signature> </Doc> It is not sufficient for the receiver to check if there is a URI in the reference and that reference points to the Approval. Because there may be some transforms in that reference which cause unexpected things. E.g -- Example 2--- <Doc> <Approval xml:id="ap">...</Approval> <Signature> ... <Reference URI="ap"> <Transforms> <Transform Algorithm="...XPath..."><XPath>0</XPath></Transform> </Transforms> </Reference> ... </Signature> </Doc> In this case there is XPath transform, which evaluates to zero or false for every node, so it ends up selecting nothing. So even though the signature seems to sign the Approval, it actually doesn't. The receiver should reject this document. Another similar example with XSLT: -- Example 3 -- <Doc> <Approval xml:id="ap">...</Approval> <Signature> ... <Reference URI="ap"> <Transforms> <Transform Algorithm="...xslt..."> <xsl:stylesheet> <xsl:template match="/"> <foo/> </xsl:template> </xsl:stylesheet> </Transform> </Transforms> </Reference> ... </Signature> </Doc> This one has an XSLT transform, which takes the incoming document, ignores it, and emits a "<foo/>" . So the actual Approval isn't signed. Obviously this one also needs to be rejected. This one is a different kind of problem (wrapping attack) -- Example 4 -- <Doc> <Approval xml:id="ap">...</Approval> <Signature> ... <Reference URI="ap2"/> ... <Object> <Approval xml:id="ap2">...</Approval> </Object> </Signature> </Doc> There are no transforms here, but notice that Reference URI is not "ap" but "ap2". And "ap2" points to another <Approval> element which is squirreled away in an Object element. An Object element allows any content. Even a sophisticated receiver that checks what is being signed could be fooled by this, because even though an Approval is signed, it is not the same approval element that is processed by the receiver. This is a kind of wrapping attack [McIntosh] Because of all these complications, it is best to severely limit the number of transforms. Some implementations can ban transforms completely and allow only simple URI based references are allowed. (Note event URI based references are subject to wrapping attacks). Banning all transforms may be too restrictive. * The Enveloped Signature transform is very useful, (in this example if the Signature were embedded inside the Approval, it would need an EnvelopedSignature transform. So we can allow that. * In some cases it is not acceptable to add an Id to the element to be signed, as this would disrupt the schema. E.g. in our example if it were not allowed to add xml:id to the Approval element, then we need a different way of identifying the element to be signed - e.g. though an XPath expression. But we do not want to allow arbitrary XPaths, because of the problem mentioned above. So we limit that to simple Xpaths in the ancestor-or-self axis only. I.e. in this case it will be "ancestor-or-self:Approval" . Note this XPath selects all Approval elements all over the document, which has the unintended side effect of solving the wrapping attack problem, i.e. now the signature includes both the Doc/Approval element and Object/Approval element so a wrapping attack is not possible. Based on these considerations we come up with the guidelines for limiting trasforms. If using IDs - EnvelopedSignature(optional) followed by C14N (optional) If not using IDs - XPath (only simple ancestor-or-self axis), EnvelopedSignature(optional), followed by C14N (optional) Note in the WS Security, STRTransform can be used in place of the C14N transform. When signing binary data, the XPath, Enveloped and C14n transforms are not applicable. Instead there should be a different set of transforms a base64 transform (optional) In case of WS Security SWA profile - an attachment content/complete transforms will be used to fetch the attachment bytes. ------------------------------------------- Section 2.1.2 sign what matters. Continuing with the previous example, lets us say that the Approval element is split up into different parts -- Example 5 -- <Doc> <Approval> <Item>Laptop</Item> <Price>700</Price> <By>Todd</By> </Approval> </Doc> Now suppose there was rule that approvals are only needed above $500. In paper forms the approver had to initial his name near the $700 amount to indicate that he is ok with that. Now lets say somebody took the idea to XML Signatures, and signed only the <Price> element. This is really bad, because now the rest of items can be easily changed. Our advice is that you include all the relevant things in the signature, so that they are all cryptographically bound together. E.g. in our example - ask What was approved?, Who did the approval? When was the approval done? and then tie all these information together into one signature. This can lead into the timestamps and nonces discussion. -------------------------------------------- Section 2.2. denial of service attacks Some XML Signature verification operations can lead to denial of service attacks. * Executing certain transforms can be extremely time consuming. It is possible to construct complex xpath and xslts transforms which take hours to validate. See dos_xpath.xml, dos_xslt.xml, dos_toomantransforms.xml * Retrieval methods in KeyInfo can go round and round in an infinite loop - see dos_retrieval_loop1.xml and dos_retrieval_loop2.xml * References to file system to other web sites can cause exception. or cross site attacks . E.g. let us say there is a URI reference file://etc/passwd. If there is some SecurityManager is place it could abort the signature verification code when trying to access this file. Another example - let us say there is an company internal hr website which is not accessible from outside. But there is this web service exposed to the outside world which accepts signed requests. Somebody from the outside world can send a signature, with a reference URI like this http://hrwebsite/addHoliday?date=May30, the web service will blindly try to dereference this URI when verifying the signature, and unintentionally add an extra holiday. Signature verification consists of reference validation, signature validation and key validation. This order of doing these operations has a great impact on resistance to attacks. * Do not do reference validation first, as that would immediately expose you to the DOS transforms mentioned earlier. * Instead get the key from the KeyInfo first. When getting the key do not follow retrieval method - as that can lead you into an infinite loop, there can also be DOS transforms in retrieval methods. Also do not follow external references. * Make sure that the key is trusted, by checking it against your trust relationships, and making sure it is not revoked or expired. * Now that you trust the key, verify the signed info. * At the very last step, verify the references. You know they came from a trusted source, so there is a low likelihood of containing a DOS transform. -------------------------------------------- Hopefully this should clarify some of the issues you brought up. Pratik Sean Mullan wrote: > > I found this draft a bit difficult to read and a bit all over the > place. It might be more useful to take a step back and reorganize it a > bit. Some of the advice is more for implementors, and some of the > advice is for signers, and other advice is for application specific > usages like WSS. I also think there's a lot of "don't do this", but > not enough of "why you should not do this". More examples would also > be useful. A section at the end with several complete signatures > abiding with most/all of the best practices would also be useful. > > I could try to suggest a different structure, if others also think it > is worthwhile. Some specific comments follow. > > Section 2.1.1 > > I found this section a bit difficult to follow. I think more of Brad's > advice/rationale could be listed. > > First paragraph: "Avoid using complicated features of XML Signature, > especially complicated transforms, since it makes it hard for the > receiver to know what was actually signed." > > That's part of the problem (and may not really be a problem if you are > using an implementation that can cache and display exactly what was > signed). The other problems are the potential DOS and other attacks > with certain transforms, and in general the added complexity and more > code involved (which inevitably has more bugs) and which makes it > harder to test all the scenarios. > > The first bullet says "First an XPath transform ...". This reads as if > we are advising that XPath be used instead of ID references. This > should be reworded. It may be better to suggest avoiding XPath, but if > necessary list some best practices (such as #2 and #3) when using it. > > Best Practice #1: an example would be useful to explain this. Also > some more details about why this is a problem. > > This section only discusses limiting transforms when signing. An > implementation may also want to reject signatures that use certain > transforms or don't abide by certain practices. > > BP #2 and #3 seem related. I would combine them into one BP about > XPath transforms. A link to the McIntosh wrapping attack paper would > also be useful here. Also, BP #3 and BP #4 are related so maybe this > should be moved to section 2.1.2. > > Unreadable sentence: "XPath Filter 2 transforms are much to understand > ...". I think it should be "much easier". If so, I don't understand > this advice. The XPath transform is a SHOULD as well. Is the advice to > avoid any transform that is not a MUST? If so, that might be good advice. > > Section 2.1.2 > > BP #4 seems inconsistent with the advice given in section 2.1.1. That > section said it is ok to sign portions of the document as long as you > use ID references or XPath transforms with some restrictions. This BP > says to sign all parts (does that mean the whole document?) unless > impractical. > > Section 2.2 > > I think we need to add more details as to why validating keys first is > better. > > "RetrievalMethods can have bad transforms, external references and > infinite loops." > > More details would be useful here. What is an external reference and > why is it bad? (I would move BP #7 before BP #6). Does this mean they > are ok in Reference URIs? It might be better to say something like > "since a RetrievalMethod is very similar to a Reference (has a URI and > Transforms), all of the issues that have been discussed with respect > to complex Transforms are also applicable. Also, a RetrievalMethod can > reference itself, which may lead to an infinite loop and a DOS attack > ..." > > BP #7: I think more details on the DOS threats with external URIs > would be useful. > > --Sean > > > > >
Received on Thursday, 29 May 2008 23:08:53 UTC