w3c / webappsec-csp

WebAppSec Content Security Policy
https://w3c.github.io/webappsec-csp/
Other
209 stars 78 forks source link

CSP: form-nonce directive #20

Open mikewest opened 9 years ago

mikewest commented 9 years ago

From @mastahyeti on August 6, 2015 5:19

The form-action directive is useful for limiting the domains to which forms can submit and could be used to limit the submission endpoints as well, though this is more difficult to implement. An interesting attack from @lcamtuf's Postcards from the post-XSS world article is the injection of a <form> above an existing <form>. Because form tags cannot be nested, the injected tag will take precedence over the legitimate one, inheriting any input tags, including any CSRF token, if present.

The form-action directive can prevent the injected form from exfiltrating the CSRF token by submitting the form to a malicious origin. It is more difficult though to prevent the injected form from submitting to an unintended same-origin endpoint. The effect of such an attack would be comparable to CSRF.

We've been playing with a few ways to protect against this attack. One approach is per-form CSRF tokens: embedded in each form's CSRF token is a signature of the intended method and action of the form. The signature is then verified by the server when the form is submitted. Another approach is to include the same form-nonce attribute in each form tag as well as in a meta tag. JavaScript then observes each form tag in the DOM and ensures that its nonce matches that of the meta tag, and otherwise deletes the form.

Both of these solutions are nasty to implement. Adding a form-nonce directive to CSP would make protecting against this attack easier for the implementer. This directive would function similarly to the JavaScript that I described. A nonce value would be provided in the CSP header and the user agent would disallow the submission of any form that didn't include the correct form-nonce attribute.

I'm curious for any thoughts on this idea, or on other protections against this attack.

/cc @mikewest @josh @oreoshake @gregose @ptoomey3

Copied from original issue: w3c/webappsec#448

mikewest commented 9 years ago

My initial thought here is that something more generic might be reasonable. That is, something like saying that <tag nonce=x> would need to be matched by </tag nonce=x> to be effective. But I'm on vacation, so who knows. :)

Let's try to address this class of problems in CSP3, and see where we get. If something more generic comes out of it, great.

ptoomey3 commented 8 years ago

I was thinking about another related attack in http://lcamtuf.coredump.cx/postxss/. Specifically, the issue with elements that allow arbitrary markup within them, such as textarea. If we had a primitive for arbitrary tags to require a nonce then we could require textareas to also have a nonce. Any textarea encountered without a nonce would be skipped when parsed.

mikewest commented 7 years ago

I do not plan to address this in CSP3. I now doubt that CSP is actually the right place to do anything... perhaps we can measure the prevalence of nested form tags and just kill them?