Skip to main content

umbraco-security-headers

Adds security headers to an Umbraco 17.3+ site: a Content Security Policy using Umbraco's per-request nonce, with separate backoffice and website policies, plus X-Frame-Options, X-Content-Type-Options, Referrer-Policy and Permissions-Policy. Two approaches: custom middleware (default) or NWebsec. Use this whenever the user asks to add a CSP or security headers to Umbraco, fix the Health Check security group (CSP, click-jacking, MIME sniffing, X-XSS-Protection, excessive headers), fix a blank backoffice or "Refused to execute inline script" errors after adding a CSP, put a nonce on an inline script (asp-csp-nonce), weigh 'strict-dynamic', make a CSP work with output caching, roll out report-only, or act on pen-test findings about headers. SKIP: non-Umbraco projects, Umbraco below 17.3, and other security work (HTTPS/HSTS, CORS, login, authorization).

Informações da origem

Repositório
umbraco/Umbraco-CMS-Implementation-Skills
Última atividade na origem
21 de outubro de 2026 às 08:31
Idioma detectado do SKILL.md
inglês
Estrelas
7
Forks
8

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
25 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
umbraco-security-headers
description
Adds security headers to an Umbraco 17.3+ site: a Content Security Policy using Umbraco's per-request nonce, with separate backoffice and website policies, plus X-Frame-Options, X-Content-Type-Options, Referrer-Policy and Permissions-Policy. Two approaches: custom middleware (default) or NWebsec. Use this whenever the user asks to add a CSP or security headers to Umbraco, fix the Health Check security group (CSP, click-jacking, MIME sniffing, X-XSS-Protection, excessive headers), fix a blank backoffice or "Refused to execute inline script" errors after adding a CSP, put a nonce on an inline script (asp-csp-nonce), weigh 'strict-dynamic', make a CSP work with output caching, roll out report-only, or act on pen-test findings about headers. SKIP: non-Umbraco projects, Umbraco below 17.3, and other security work (HTTPS/HSTS, CORS, login, authorization).
# Security Headers Two supported ways to send a CSP and the other security headers: | | **A — Custom middleware** (default) | **B — NWebsec** | |---|---|---| | Reference | [approach-a-middleware.md](references/approach-a-middleware.md) | [approach-b-nwebsec.md](references/approach-b-nwebsec.md) | | Source | Verified code in `assets/` | The docs' NWebsec sample, scoped per surface | | Dependencies | None | `NWebsec.AspNetCore.Middleware` | | Wiring | A composer adds it to Umbraco's pipeline | Program.cs, before `app.UseUmbraco()` | | Best for | New CSP work, packages, sites without NWebsec | Sites that already use NWebsec | ### How to decide Default to A. Choose B when the project already configures headers with NWebsec: extend that setup rather than adding a second source of the same headers. Never run both. **Before writing any code, open the reference for the approach you choose,** and for A start from the files in `assets/`. The steps, and the order the headers must be set in, are only there. ## Version compatibility Targets **Umbraco 17.3+**. `ICspNonceService`, `UseUmbracoCspNonceInjection()` and the `asp-csp-nonce` tag helper first ship in 17.3.0, so check the `Umbraco.Cms` version first. On 17.0 to 17.2 there is no nonce to use, so recommend upgrading before adding a CSP. ## Best practices - **Two surfaces, two policies.** The backoffice under `/umbraco` needs `script-src 'self'` plus the nonce, `style-src 'self' 'unsafe-inline'`, `img-src 'self' blob: data: https://news-dashboard.umbraco.com` and `frame-src 'self' https://marketplace.umbraco.com`. The website should get none of the Umbraco hosts and no `'unsafe-inline'`, except in `style-src` when inline `style="…"` attributes (which can't take a nonce) can't be moved to CSS. Browsers ignore `'unsafe-inline'` in a directive that also has a nonce, so in that case drop the nonce from `style-src`. Its own sources (analytics, fonts, CDN) don't belong in the backoffice's. - **The nonce is per request.** Umbraco tags its backoffice import map with it. For your own inline `<script>`/`<style>`, add `asp-csp-nonce` and register the tag helper with `@addTagHelper *, Umbraco.Web.Common`. Note the assembly is `Umbraco.Web.Common`, not `Umbraco.Cms.Web.Common`: with the wrong name the attribute renders literally and the script is blocked. Never hard-code a nonce, and never add `'unsafe-inline'` to `script-src` to fix a violation. - **Keep `'self'` in the backoffice `script-src`, and don't add `'strict-dynamic'`.** In 17.5.3 the backoffice entry script carries no nonce (it registers the tag helper under the wrong assembly name too) and loads only because of `'self'`, which `'strict-dynamic'` disables. - **Output caching.** Umbraco's website output cache replays the header and HTML it stored, so a cached page reuses one nonce for every visitor until the entry expires. On cached pages, prefer a hash or an external file for inline scripts. - **Send one of each header.** A second `Content-Security-Policy` (from `Append` next to NWebsec, a second middleware, or a CDN rule) is enforced as well, and it has no nonce. Check what the CDN or proxy adds before adding the same header in the app. - **Roll out with `Content-Security-Policy-Report-Only`,** read the violations in the browser console, then switch to enforcing. The CSP health check only passes on the enforcing header. - **Framing.** Use `X-Frame-Options: SAMEORIGIN` with `frame-ancestors 'self'`. Backoffice preview shows the page in a same-origin iframe, so `DENY` or `'none'` breaks preview. - **Don't send `X-XSS-Protection`.** It is deprecated, and the health check flags it with any value, `0` included. - **`Server` and `X-Powered-By` come from the host,** so middleware can't remove them. Follow [Excessive Headers](https://docs.umbraco.com/umbraco-cms/run-in-production/infrastructure-and-ops/health-check/guides/excessiveheaders.md) (Kestrel `AddServerHeader = false`, or `web.config` on IIS). ## Verify A header change is done when a response shows it, not when it compiles: - `curl -sI https://<site>/` and `curl -s -D - -o /dev/null https://<site>/umbraco` (GET, because `HEAD /umbraco` returns 404): each response has one CSP, its own policy, and the other headers. Check a media or static file and a 404 too. - The nonce in the `/umbraco` header equals the `nonce` on `<script type="importmap">` in its HTML. On a site page, any `asp-csp-nonce` tag renders as `nonce="…"` with the header's value. - Sign in to the backoffice with the console open, open a document and preview it. Expect no CSP violations. - The Health Check security group needs `UmbracoApplicationUrl` set, because it requests that URL. If the site can't be run, say which of these checks weren't made. ## Validation Objective assertions live in [`evals/evals.json`](evals/evals.json); run them with `umbraco-skill-evaluator`. [`evals/README.md`](evals/README.md) has the inputs, the run-prompt rules and the grading notes. Approach A is **Asserted** by the `dotnet test` gate (`examples/approach-a-middleware/`). Approach B ships no code, so its tier is **Documented**.
Ver no GitHub