CentralCSP
PoliciesContent-Security-PolicyDirectives

base-uri

The CSP base-uri directive restricts the URLs allowed in a base element href, closing a common base-tag injection XSS vector.

Last update:

The base-uri directive controls which URLs can appear in a document's <base href> element. The <base> tag rewrites the base URL that every relative link, script, and form on the page resolves against, so an attacker who can inject one <base> tag can silently point all of your relative script URLs at a server they control. base-uri is the directive that shuts that down.

Most sites never set a <base> tag, so lock it down entirely:

Content-Security-Policy: base-uri 'none'

Fallback chain

base-uri has no fallback. default-src does not cover it, so if you leave it out of your policy, there is no restriction on <base> at all, no matter how strict the rest of your CSP is. That makes omitting it one of the most common and most dangerous gaps in an otherwise solid policy.

Values

base-uri takes a source list, the same value grammar as the fetch directives, but it does not accept nonces or hashes (those describe content, not a base URL).

ValueStatusDescription
'none'✅ GoodForbids any <base> element from setting a base URL. The recommended choice for most sites.
'self'✅ GoodAllows a <base href> only on the document's own origin (scheme, host, and port).
Host or scheme source✅ GoodAllows a <base href> matching that host source or scheme source. Rarely needed.

If a <base> element's href does not match the source list, the browser ignores that element and the page keeps resolving relative URLs against the document URL.

Most sites do not need a <base> tag at all, so base-uri 'none' is the right default. Use 'self' only if your application genuinely sets a same-origin base URL. Do not use a wildcard or a broad scheme like https:: a permissive value defeats the point of the directive, because it lets an injected <base> tag redirect relative URLs to any host on that scheme.

Examples

Lock down <base> completely for a typical strict policy:

Content-Security-Policy:
    script-src 'nonce-r4nd0m' 'strict-dynamic';
    object-src 'none';
    base-uri 'none'

Allow only a same-origin base URL when your app sets one:

Content-Security-Policy: base-uri 'self'

Security notes

base-uri blocks base-tag injection, a cross-site scripting (XSS) escalation that turns a single injected tag into control over many resources at once. Consider a page that loads scripts with relative paths:

<script src="/js/app.js"></script>

If an attacker injects <base href="https://evil.example/"> earlier in the document, the browser resolves /js/app.js against the attacker's origin and loads their code instead. Your script-src allowlist may still apply, but a host-based allowlist that trusts the document origin can be sidestepped, and even a nonce-based policy can be undermined when relative URLs move. Setting base-uri 'none' removes the <base> lever entirely.

Known bypasses and risks

base-uri only governs the <base> element. It does not stop an attacker who can inject a fully qualified script URL directly, that is the job of script-src. Treat base-uri as one layer in a strict policy, not a standalone control.

The bigger risk is omission, not misconfiguration. A policy with a strong script-src but no base-uri still carries the base-tag injection gap, and the mistake is easy to make because nothing else in the policy hints at it. Run your policy through the CSP evaluator to catch a missing base-uri before it ships.

Recommendation

Content-Security-Policy: base-uri 'none'

Ship base-uri 'none' unless your application sets a same-origin <base>, in which case use 'self'. Both the OWASP CSP cheat sheet and the web.dev strict CSP guidance include base-uri 'none' in the strict policy, next to a nonce-based script-src and object-src 'none', because the three together close the main script-injection escalation paths.

Reporting

When the directive blocks a <base> element, the browser emits a csp-violation report naming base-uri as the effective directive. Wire delivery with the report-to directive and the Reporting-Endpoints header.

Browser support

base-uri is part of CSP Level 2 and Level 3 and is widely supported across current browsers.

FAQ

What does base-uri protect against?

base-uri blocks base-tag injection, an XSS escalation where an injected <base href> rewrites the URL that every relative script and link resolves against, silently pointing them at an attacker's server. Setting base-uri 'none' removes the <base> lever entirely, even when the rest of your policy is strict.

Should I set base-uri to none?

Yes for most sites. Few pages set a <base> tag, so base-uri 'none' is the right default and forbids any <base> element from setting a base URL. Use 'self' only if your application genuinely sets a same-origin base URL. Avoid a wildcard or a broad scheme like https:.

See also

Sources

On this page