Re: Best Practices comments

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