form-actionform-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.