IM.ContentSecurityPolicy · Umbraco 13–18

Restrykcyjny CSP bez ręcznych nonce

Nagłówki Content Security Policy i nowy nonce dla każdego żądania, dla ASP.NET Core i Umbraco. Pakiet sam dodaje nonce do tagów script, style i link.

Pakiet
Instalacjadotnet add package IM.ContentSecurityPolicy
Wersja2.0.4
Umbraco13–18
.NET8, 9, 10
Co robi

Trzy zadania przy każdym żądaniu

Nonce dla każdego żądania

  • Losowa wartość z kryptograficznie bezpiecznego generatora, dostępna w widokach i w kodzie.

Nagłówek CSP z Twoich ustawień

  • Content-Security-Policy albo Report-Only na czas testów, zbudowany z opcji, które kontrolujesz.

Nonce w Twoich tagach

  • Dodawany do tagów script, style i link przez tag helper, helpery HTML albo view components.
Pierwsze kroki

Instalacja i rejestracja

01

Dodaj pakiet

Jeden pakiet dla Umbraco 13–18 i czystego ASP.NET Core.

dotnet add package IM.ContentSecurityPolicy

02

Zarejestruj middleware

W Program.cs. Najpierw generowanie nonce, żeby nagłówek mógł go użyć.

builder.Services.AddNonceServices();

var app = builder.Build();

app.UseNonceGeneration();
app.UseContentSecurityPolicy();

03

Zarejestruj helpery raz

W Views/_ViewImports.cshtml, żeby każdy widok mógł dodać nonce.

@addTagHelper *, IM.ContentSecurityPolicy
@using IM.ContentSecurityPolicy.Extensions

W widokach

Cztery sposoby na dodanie nonce

01 Tag helper

Dodaj asp-nonce="true" do tagów script, style i link. Nonce bieżącego żądania zostanie wpisany automatycznie.

<script src="~/js/site.js" asp-nonce="true"></script>

<style asp-nonce="true">
  .hero { color: #3544b1; }
</style>

<link rel="stylesheet" href="~/css/site.css" asp-nonce="true" />
02 Helpery HTML

Dla tagów budowanych w Razorze. Helpery nie kodują wejścia jako HTML, więc przekazuj tylko zaufane wartości.

@Html.ScriptWithNonce("~/js/site.js")
@Html.InlineScriptWithNonce("console.log('ready');")
@Html.StyleWithNonce("~/css/site.css")
@Html.InlineStyleWithNonce(".hero { color: #3544b1; }")

<script @Html.GetNonceAttribute()>
  window.dataLayer = window.dataLayer || [];
</script>
03 View components

NonceScript, NonceInlineScript, NonceStyle i NonceInlineStyle. Każdy potrzebuje swojego widoku, np. Views/Shared/Components/NonceScript/Default.cshtml.

@await Component.InvokeAsync("NonceScript", new { src = "~/js/site.js" })
04 Własny kod

Wstrzyknij INonceService. GetNonce() zwraca nonce bieżącego żądania, a HasNonce() mówi, czy istnieje.

public class ScriptsController(INonceService nonces) : Controller
{
    public IActionResult Index()
    {
        ViewData["Nonce"] = nonces.GetNonce();
        return View();
    }
}
Polityka

Najpierw test, potem egzekwowanie

01

Report-Only na czas testów

Przeglądarka zgłasza, co polityka by zablokowała, ale niczego nie blokuje.

  • Ustaw ReportOnly i ReportUri
  • Zobacz, które skrypty i style nie mają jeszcze nonce
  • Odwiedzający niczego nie zauważą

02

Egzekwowanie

Wyłącz Report-Only, gdy raporty są czyste.

  • Przeglądarka blokuje wszystko bez poprawnego nonce lub dozwolonego źródła
  • Nowy nonce przy każdym żądaniu
  • Zostaw ReportUri, żeby wyłapać regresje
Konfiguracja

Ustaw źródła

Opcje

Ustaw źródła

{nonce} jest podmieniany przy każdym żądaniu.

builder.Services.AddNonceServices(options =>
{
    options.ScriptSrc = new[] { "'self'", "'nonce-{nonce}'", "https://cdn.example.com" };
    options.ReportOnly = true;
    options.ReportUri = "/csp-report";
});

Builder

Zacznij od restrykcyjnego presetu

CspOptionsBuilder daje restrykcyjną politykę, którą możesz rozszerzać.

var options = CspOptionsBuilder.CreateStrict()
    .WithScriptSrc("'self'", "'nonce-{nonce}'")
    .WithReportUri("/csp-report")
    .Build();
Zgodność

Jeden pakiet dla Umbraco 13–18

Umbraco .NET Wersja pakietu
13 LTS, 14 8 2.x
15, 16 9 2.x
17 LTS, 18 10 2.x
10–12 6, 7 1.0.2
W praktyce

Na naszej stronie

01 · Nagłówek odpowiedzi

Polityka, którą wysyła ideamakers.pl

Skrypty i style działają tylko z naszej domeny albo z nonce danego żądania. Bez 'unsafe-inline', bez wtyczek i bez osadzania strony przez inne witryny.

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-qTQx0elxVNpegG/7B+tAYA==' https://challenges.cloudflare.com;
  style-src 'self' 'nonce-qTQx0elxVNpegG/7B+tAYA==' 'sha256-Kh2l25Sy4DYc/g2Mm3KwI0W8tow97xzNP6zUE8/2UHE=';
  img-src 'self' data:;
  font-src 'self' data:;
  connect-src 'self';
  frame-src 'self' https://challenges.cloudflare.com;
  object-src 'none';
  base-uri 'self';
  form-action 'self';
  frame-ancestors 'self'

02 · Dwa żądania

Za każdym razem nowy nonce

Ta sama strona pobrana dwa razy dostaje dwie różne wartości, więc nonce skopiowany z jednej odpowiedzi jest bezużyteczny w następnej.

GET https://ideamakers.pl/en/contact/
  script-src 'self' 'nonce-74KxrM8xVoaTobkUhxHTZA==' ...

GET https://ideamakers.pl/en/contact/
  script-src 'self' 'nonce-qTQx0elxVNpegG/7B+tAYA==' ...

03 · Źródło strony

Nonce przy każdym skrypcie

Dane strukturalne, stan zgód i skrypty inline mają nonce danej odpowiedzi.

<script type="application/ld+json" nonce="qTQx0elxVNpegG/7B+tAYA==">
<script id="im-consent-state" type="application/json" nonce="qTQx0elxVNpegG/7B+tAYA==">
<script nonce="qTQx0elxVNpegG/7B+tAYA==">

Chcesz restrykcyjny CSP na swojej stronie w Umbraco?

Skonfigurujemy politykę, przeniesiemy skrypty inline na nonce i najpierw przetestujemy wszystko w trybie Report-Only.