# base-uri (/en/docs/web-security/policies/content-security-policy/directives/base-uri)



The `base-uri` directive controls which URLs can appear in a document's
[`<base href>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/base)
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:

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

## Fallback chain [#fallback-chain]

`base-uri` has no fallback. [`default-src`](/en/docs/web-security/policies/content-security-policy/directives/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 [#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).

| Value                 | Status | Description                                                                                                                                                                                                                                           |
| --------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `'none'`              | ✅ Good | Forbids any `<base>` element from setting a base URL. The recommended choice for most sites.                                                                                                                                                          |
| `'self'`              | ✅ Good | Allows a `<base href>` only on the document's own origin (scheme, host, and port).                                                                                                                                                                    |
| Host or scheme source | ✅ Good | Allows a `<base href>` matching that [host source](/en/docs/web-security/policies/content-security-policy/values/csp-host-source) or [scheme source](/en/docs/web-security/policies/content-security-policy/values/csp-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 [#examples]

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

```http
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:

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

## Security notes [#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:

```html
<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 [#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`](/en/docs/web-security/policies/content-security-policy/directives/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](/tools/csp-evaluator) to catch a missing
`base-uri` before it ships.

## Recommendation [#recommendation]

```http
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](https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html)
and the [web.dev strict CSP guidance](https://web.dev/articles/strict-csp) 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 [#reporting]

When the directive blocks a `<base>` element, the browser emits a
[`csp-violation` report](/en/docs/web-security/reporting-api/reports/csp-violation)
naming `base-uri` as the effective directive. Wire delivery with the
[`report-to` directive](/en/docs/web-security/policies/content-security-policy/directives/report-to)
and the [`Reporting-Endpoints` header](/en/docs/web-security/reporting-api/headers/reporting-endpoints).

## Browser support [#browser-support]

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

## FAQ [#faq]

### What does base-uri protect against? [#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? [#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 [#see-also]

* [default-src](/en/docs/web-security/policies/content-security-policy/directives/default-src)
* [form-action](/en/docs/web-security/policies/content-security-policy/directives/form-action)
* [script-src](/en/docs/web-security/policies/content-security-policy/directives/script-src)
* [object-src](/en/docs/web-security/policies/content-security-policy/directives/object-src)
* [CSP keyword values](/en/docs/web-security/policies/content-security-policy/values/csp-keywords)

## Sources [#sources]

* [MDN, CSP base-uri](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/base-uri)
* [W3C, Content Security Policy Level 3](https://www.w3.org/TR/CSP3/)
* [OWASP, Content Security Policy cheat sheet](https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html)
* [web.dev, strict CSP](https://web.dev/articles/strict-csp)
