Skip to content

CSP: form-nonce directive #20

Open
@mikewest

Description

@mikewest

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions