How to prevent base tag hijacking and form action redirection?

csp-injection-directives-missingglobal

CSP provides directives beyond script-src that prevent injection attacks operating outside script execution. base-uri controls which URLs the <base> element can set, preventing relative URL hijacking. form-action controls where forms can submit data, preventing credential exfiltration through action attribute injection. Both directives are absent from most policies because teams focus on script-src and assume other injection vectors are covered.

What’s wrong

The Content Security Policy lacks base-uri and form-action directives. Without base-uri, an attacker who achieves even limited HTML injection can insert a <base> tag that changes the base URL for all relative references on the page. Scripts, images, stylesheets, and links resolve against the attacker-controlled base instead of the legitimate origin. Without form-action, injected HTML can modify or create form elements that submit credentials and user input to external endpoints. Neither attack requires script execution, so script-src provides no protection.

Why it matters

Base tag hijacking is subtle. A single injected <base href="https://attacker.example"> tag rewrites every relative URL on the page. Script tags with relative src attributes load from the attacker’s server. Resource requests silently redirect. The page appears functional because the DOM structure is unchanged — only the resolution context shifts. Form action injection is a direct credential theft vector. An injected form or a modified action attribute sends user input — passwords, payment details, personal data — to an attacker-controlled endpoint. The user sees the legitimate page and has no indication that submission targets have changed. Both attacks succeed in environments with strict script-src policies because they operate through HTML attributes, not script execution.

The correct change

Add base-uri and form-action directives to the Content-Security-Policy header. Set base-uri to ‘self’ or ‘none’ depending on whether the site uses the <base> element. Most sites do not use <base> and should set base-uri to ‘none’. Set form-action to ‘self’ or list specific origins where forms legitimately submit. Payment processors, authentication providers, and third-party form handlers must be explicitly listed. The end state is a policy where relative URL resolution and form submission targets cannot be manipulated through injection.

Scope

This condition applies globally. Both directives operate at the page level through the Content-Security-Policy header. base-uri affects all relative URL resolution on the page. form-action affects every form element. Global configuration ensures consistent protection across all pages.

How to verify

  • Validation confirms the condition is resolved:
  • • Content-Security-Policy header includes base-uri directive
  • • Content-Security-Policy header includes form-action directive
  • • base-uri set to ‘none’ or ‘self’ based on site requirements
  • • form-action limited to ‘self’ and explicitly listed submission targets
  • • Injected <base> tags with external hrefs are blocked by the browser
  • • Forms with modified action attributes pointing to unauthorized origins fail to submit
  • • Browser console shows CSP violations when injection is attempted
  • • Legitimate form submissions to permitted origins continue to work

Takeaway

  • script-src alone does not prevent all injection attacks
  • base-uri prevents relative URL hijacking through <base> tag injection
  • form-action prevents credential theft through form submission redirection
  • Both directives block attacks that operate through HTML attributes without script execution

FAQ

Why doesn’t script-src protect against these attacks?

script-src controls script execution sources. Base tag hijacking and form action redirection operate through HTML attributes, not script execution. A <base> tag changes URL resolution for all relative references. A form action attribute changes where data is submitted. Neither requires running JavaScript. These are injection attacks that exploit document structure, not code execution.

Do most sites actually use the <base> element?

No. The <base> element is uncommon in modern web applications. Most sites use absolute paths or framework-managed routing that does not depend on base URL resolution. If the site does not use <base>, set base-uri to ‘none’. This eliminates the attack surface entirely without affecting functionality.

What breaks when form-action is restricted?

Forms that submit to third-party endpoints will fail unless those origins are listed in the directive. Common examples include payment gateways, OAuth providers, search engines for site search, and newsletter services. Audit all form action targets before deploying. Add legitimate third-party submission endpoints to the form-action allow list.

Can base tag hijacking really exfiltrate data without JavaScript?

Yes. When relative URLs resolve against an attacker-controlled base, resource requests — script loads, image fetches, stylesheet requests — go to the attacker’s server. The attacker sees what resources the page requested and can serve modified versions. If the page uses relative action attributes on forms, those submissions also redirect to the attacker. No JavaScript is required at any point.

Should form-action include ‘self’ or list origins explicitly?

‘self’ allows submission to the same origin, which covers most standard form handling. Add explicit origins only for legitimate cross-origin submissions. Avoid wildcards. Each listed origin can receive any form data from the page, so the list should be minimal. Review periodically as integrations change.

How do these directives interact with Content-Security-Policy-Report-Only?

Both directives work in report-only mode. Deploy with Content-Security-Policy-Report-Only first to identify forms submitting to unexpected origins or pages using <base> elements. Review violation reports before switching to enforcement. This prevents breaking legitimate functionality during rollout.

The fix

Prevent injection attacks that operate outside script execution by restricting base URL resolution and form submission targets

Done when: Content-Security-Policy includes base-uri and form-action directives, preventing base tag hijacking and form action redirection regardless of script-src configuration

Do not

  • Do not assume script-src covers all injection vectors
  • Do not omit form-action because forms seem simple
  • Do not use wildcard origins in base-uri or form-action
  • Do not forget to audit existing form submission targets before restricting form-action

How to verify

  • Content-Security-Policy includes base-uri directive
  • Content-Security-Policy includes form-action directive
  • Injected <base> tags blocked by browser
  • Unauthorized form action redirections blocked
  • CSP violation logged when injection is attempted
  • Legitimate form submissions to permitted origins succeed

Find every page with this

probeo monitors this continuously across every page of your site, and records which pages passed, which failed, and which it could not determine.

Book a Call