base-uri
base-uri restricts the URLs that may appear in a document’s <base> element.
It matters out of all proportion to its size. An attacker who can inject a single <base href="https://attacker.example/"> re-points every relative URL on the page, scripts included, without ever injecting a script tag.
A nonce-based script-src is exactly the policy this defeats: the nonce authorises the <script> element, and the base tag decides where that element loads from. script-src 'self' happens to catch it, because the rewritten URL is no longer same-origin - but a policy built on nonces and 'strict-dynamic' has no host check left to catch it with.
base-uri does not fall back to default-src. Leaving it out allows any base URL, whatever the rest of the policy says.
Syntax
Section titled “Syntax”Content-Security-Policy: base-uri 'none';Content-Security-Policy: base-uri <source-expression-list>;What it controls
Section titled “What it controls”- The
hrefof a<base>element.
Fallback
Section titled “Fallback”base-uri has no fallback. If it is absent from the policy it restricts nothing, whatever default-src says.
Recommended value
Section titled “Recommended value”Content-Security-Policy: base-uri 'self'- Or
'none'if you never use<base>, which is most sites. Either one closes the hijack; neither costs anything. - This belongs in every policy alongside
object-src 'none'. Both are one line and neither has a legitimate cost - andbase-uriis the one of the two thatdefault-srccannot stand in for, which is why it is the one that gets forgotten.
Examples
Section titled “Examples”Allowed
Section titled “Allowed”Under base-uri 'self':
<base href="/app/" />Blocked
Section titled “Blocked”Under base-uri 'self', an injected base tag:
<base href="https://attacker.example/" />Browser support
Section titled “Browser support”- Widely available across browsers since January 2020.
In a HeaderHawk report
Section titled “In a HeaderHawk report”| Field | Value |
|---|---|
violatedDirective |
base-uri |
effectiveDirective |
base-uri |
blockedUri |
https://attacker.example/ |
| Issue title | base-uri blocking attacker.example |
- Traffic on this directive deserves a look every time. A legitimate
<base>is set once by your own template and reports a host you recognise; anything else on this directive is worth treating as an injection until you have proved otherwise. - This is a good candidate for an alert rule: the expected volume is zero.
Related directives
Section titled “Related directives”Getting reports for this directive
Section titled “Getting reports for this directive”Point your policy’s report-uri at your site’s HeaderHawk endpoint and the violations above arrive in the dashboard, grouped as described. The Quick Start sets that up in five minutes, and the integration guides cover the header syntax for each platform.