form-action
form-action
directive allows you to specify to what location a form may POST to.The most common way to use the form-action
directive is to only allow forms to be POST to the same origin, or same domain name. This is accomplished in CSP using the self
source list keyword.
form-action 'self'
The above CSP policy would allow this form work (because /search will be on the same origin, or same domain and scheme):
<form action="/search"> <input type="search" name="query"> <input type="submit" value="Search"> </form>
However the browsers CSP engine would block the following form from posting to the external site:
<form action="https://attackers.example.com/login"> <input type="password" name="password"> <input type="submit" value="Login"> </form>
Allowing a different form action
Now suppose we want to allow a form action pointing to https://a.example.com and https://b.example.com we can specify these domains in form-action
like this:
form-action https://a.example.com https://b.example.com
If we wanted to keep 'self' in there we could add that as well:
form-action 'self' https://a.example.com https://b.example.com
Yes, you can use the form-action
directive from a Content-Security-Policy meta tag. It can also be specified as part of a Content-Security-Policy
header.
No, the form-action
does not inherit from the default-src
directive, you need to explicitly specify it in your Content-Security-Policy
header.
If your web application should not post forms anywhere you can enforce this in the CSP policy by using the 'none' source list keyword. For example:
form-action: 'none';
This question is currently debated, and as a result browser vendors have different implementations regarding what happens when a form is redirected to a different url.
Form data can be sent to the redirected url if the HTTP status code is 307
or 308
, which makes the redirect potentially sensitive.
Currently Firefox allows the redirect, while Chrome and Safari will block them.
In Chrome, if I have a CSP policy of form-action 'self'
and I submit a form to /redirect, which does a 302 redirect to a different domain, I would see an error like this:
Refused to send form data to '<URL>' because it violates the following Content Security Policy directive: "form-action 'self'".
To resolve this you need to make sure any URI that is redirected to is included in form-action
directive.
form-action
blocks something?You might see an error message in the developer tools console such when you try to submit a form whose action is not allowed by the form-action
policy, such as:
[Error] Refused to load <url> because it does not appear in the form-action directive of the content security policy.
Or you may see an error like this when a form attempts to submit to an action url that is not on the same origin (self), which would violate a form-action 'self'
content security policy directive:
Refused to load because an ancestor violates the following content security policy directive: "form-action 'self'".
If the form is submitted via an AJAX call such as XmlHttpRequest or via Fetch, then it would fall under the connect-src CSP directive.
The form-action
directive was added to CSP Level 2. This means that browser support for form-action existed since 2015 in Chrome (version 40) and Firefox (version 36), Safari 10+ or Edge 15+.
The form-action CSP directive is not supported at all in Internet Explorer, you need to use the Edge browser instead.
Want to learn the ins and outs CSP? Grab a copy of the CSP Developer Field Guide. It's a short and sweet guide to help developers get up to speed quickly.
Grab a CopyAdvisory Week is a weekly roundup of all the security advisories published by the major software vendors.