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.
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.
Instalacja i rejestracja
01
Dodaj pakiet
Jeden pakiet dla Umbraco 13–18 i czystego ASP.NET Core.
dotnet add package IM.ContentSecurityPolicy02
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.ExtensionsW 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();
}
} 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
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();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 |
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==">Pytania, błędy i pomysły
Chcesz restrykcyjny CSP na swojej stronie w Umbraco?
Skonfigurujemy politykę, przeniesiemy skrypty inline na nonce i najpierw przetestujemy wszystko w trybie Report-Only.