How to prevent base tag hijacking and form action redirection?
csp-injection-directives-missing global
The issue
A policy without base-uri and form-action leaves two injection routes open that script-src can’t close. An injected <base> tag can send every relative URL on the page, including script paths, to another server. An injected or altered form can send what visitors type, passwords and card details included, somewhere else. The page looks unchanged in both cases.
The cause is that neither directive falls back to default-src. A policy that doesn’t set them places no limit on either, however strict the rest of it is.
Scope
Both directives apply to the whole document that receives the policy: base-uri to its <base> element, form-action to every form on it. They are normally set once, in the shared policy.
How to check you have it
- In probeo: a policy without them is reported as
csp:missing-base-uriandcsp:missing-form-action, graded minor. A policy that allows any web origin for either is reported ascsp:base-uri-wildcardorcsp:form-action-wildcard. - By hand: run
curl -sI https://your-site.example/ | grep -i content-security-policyand look forbase-uriandform-action. - With a tool: Google’s CSP Evaluator flags a missing
base-uri.
The fix
Add base-uri 'none' and form-action 'self' to the Content Security Policy.
Use base-uri 'self' instead if the site uses a <base> element. For form-action, list each other origin forms really submit to, such as a payment provider or a sign-in service, and nothing more.
Done when: the policy sets both directives to 'none', 'self' or a short list of named origins, and the check above comes back clean.
Do not
- Do not assume
script-srccovers these routes. - Do not leave
form-actionout because the site’s forms seem simple. - Do not use a wildcard in
base-uriorform-action. - Do not restrict
form-actionbefore finding every place forms submit to.
FAQ
Why doesn’t script-src protect against these attacks?
Neither route needs a script to run. A <base> tag changes how relative URLs resolve, and a form’s action changes where its data goes. Both are plain HTML.
Do most sites actually use the <base> element?
Most don’t. If yours doesn’t, base-uri 'none' costs nothing.
What breaks when form-action is restricted?
Forms that submit to another origin, such as payment gateways, sign-in providers or newsletter services, stop working until that origin is listed. Find them before enforcing.
Can base tag hijacking really exfiltrate data without JavaScript?
It can redirect requests without JavaScript. Relative script, stylesheet and image requests go to the attacker’s server, which can serve its own versions, and forms with relative actions submit there too.
Should form-action include ‘self’ or list origins explicitly?
Start with 'self' and add only the other origins forms really submit to. Every origin listed can receive whatever a form on the page sends.
How do these directives interact with Content-Security-Policy-Report-Only?
They work in report-only mode too. Running them there first shows which forms submit elsewhere and which pages use <base>, before anything is blocked.
Which product detects this
Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.