Content Security Policy¶
Content Security Policy (CSP) är en webbsäkerhetsstandard som hjälper till att förebygga innehållsinjektionsangrepp genom att begränsa vilka källor innehåll får laddas från. Den spelar en viktig roll i en heltäckande säkerhetsstrategi.
Instruktioner för konfiguration i ett Django-projekt finns i dokumentationen Använda CSP. En HTTP-guide till CSP finns i MDN:s guide om CSP.
Översikt¶
Specifikationen Content-Security-Policy definierar två kompletterande rubriker:
Content-Security-Policy: Verkställer CSP-policyn och blockerar innehåll som bryter mot de definierade direktiven.Content-Security-Policy-Report-Only: Rapporterar CSP-överträdelser utan att blockera innehåll, vilket möjliggör icke-störande tester.
Varje policy består av ett eller flera direktiv och deras värden, som tillsammans instruerar webbläsaren om hur den ska hantera specifika typer av innehåll.
När ContentSecurityPolicyMiddleware är aktiverad skapar och bifogar Django automatiskt lämpliga rubriker till varje svar baserat på de konfigurerade inställningarna, om de inte redan har satts av ett annat lager.
Inställningar¶
Klassen ContentSecurityPolicyMiddleware konfigureras med följande inställningar:
SECURE_CSP: definierar den verkställande Content Security Policy.SECURE_CSP_REPORT_ONLY: definierar en Content Security Policy enbart för rapportering.
Dessa inställningar kan användas oberoende av varandra eller tillsammans
Använd endast
SECURE_CSPför att verkställa en policy som redan har testats och verifierats.Använd
SECURE_CSP_REPORT_ONLYför sig för att utvärdera en ny policy utan att störa webbplatsens beteende. Detta läge blockerar inte överträdelser utan loggar dem bara. Det är användbart för testning och övervakning, men ger inget skydd mot aktiva hot.Använd båda för att behålla en verkställd baslinje samtidigt som du experimenterar med ändringar. Även för väletablerade policyer kan fortsatt insamling av rapporter hjälpa till att upptäcka regressioner, oväntade beteendeförändringar eller potentiell manipulering i produktionsmiljöer.
Rapporter om policyöverträdelser¶
När en CSP-överträdelse inträffar loggar webbläsare vanligtvis detaljer i utvecklarkonsolen, vilket ger omedelbar återkoppling under utveckling. För att också ta emot rapporterna programmatiskt måste policyn innehålla ett rapporteringsdirektiv såsom report-uri som anger vart överträdelsedata ska skickas.
Django stöder konfiguration av dessa direktiv via inställningen SECURE_CSP_REPORT_ONLY, men rapporter utfärdas endast av webbläsaren om policyn uttryckligen innehåller ett giltigt rapporteringsdirektiv.
Django tillhandahåller inte inbyggd funktionalitet för att ta emot, lagra eller behandla överträdelserapporter. För att samla in och analysera dem måste du implementera en egen rapporteringsändpunkt eller integrera med en övervakningstjänst från tredje part.
CSP-konstanter¶
Django tillhandahåller fördefinierade konstanter som representerar vanliga nyckelord för CSP-källuttryck, såsom 'self', 'none' och 'unsafe-inline'. Konstanterna är avsedda att användas i direktivvärden som definieras i inställningarna.
De är tillgängliga via uppräkningen CSP, och det rekommenderas att använda dem i stället för råa strängar. Det bidrar till att undvika vanliga fel såsom stavfel, felaktig citering eller inkonsekvent formatering och säkerställer överensstämmelse med CSP-specifikationen.
- class CSP[source]¶
Uppräkning som tillhandahåller standardiserade konstanter för vanliga CSP-källuttryck.
- NONE¶
Representerar
'none'. Blockerar inläsning av resurser för det angivna direktivet.
- REPORT_SAMPLE¶
Representerar
'report-sample'. Instruerar webbläsaren att inkludera ett prov av den överträdande koden i rapporter. Observera att detta kan exponera känsliga data.
- SELF¶
Representerar
'self'. Tillåter att resurser laddas från samma ursprung (samma schema, värd och port).
- STRICT_DYNAMIC¶
Representerar
'strict-dynamic'. Tillåter körning av skript som laddas av ett betrott skript (till exempel ett med giltig nonce eller hash) utan att'unsafe-inline'krävs.
- UNSAFE_EVAL¶
Representerar
'unsafe-eval'. Tillåter användning aveval()och liknande JavaScript-funktioner. Starkt avrått.
- UNSAFE_HASHES¶
Representerar
'unsafe-hashes'. Tillåter infogade händelsehanterare och vissajavascript:-URI:er när deras innehållshashar matchar en policyregel. Kräver CSP nivå 3 eller senare.
- UNSAFE_INLINE¶
Representerar
'unsafe-inline'. Tillåter körning av infogade skript, stilar ochjavascript:-URL:er. Generellt avrått, särskilt för skript.
- WASM_UNSAFE_EVAL¶
Representerar
'wasm-unsafe-eval'. Tillåter kompilering och körning av WebAssembly-kod utan att aktivera'unsafe-eval'för skript.
- NONCE¶
Django-specifikt platshållarvärde (
"<CSP_NONCE_SENTINEL>") som används i direktivenscript-srcellerstyle-srcför att aktivera nonce-baserad CSP. Strängen ersätts vid körning avContentSecurityPolicyMiddlewaremed en säker slumpmässig nonce som skapas för varje begäran. Se den detaljerade förklaringen i Användning av nonce.
Dekoratörer¶
Django tillhandahåller dekoratorer för att styra Content Security Policy-rubriker per vy. De gör det möjligt att åsidosätta eller inaktivera den verkställande policyn eller policyn för enbart rapportering i specifika vyer och ger detaljerad kontroll när de globala inställningarna inte räcker. Dessa åsidosättningar ersätter helt bas-CSP:n; de sammanfogas inte med befintliga regler. De kan användas tillsammans med konstanterna i CSP.
Varning
Att försvaga eller inaktivera en CSP-policy på någon sida kan äventyra hela webbplatsens säkerhet. På grund av policyn för ”samma ursprung” kan en angripare utnyttja en sårbarhet på en sida för att komma åt andra delar av webbplatsen.
- csp_override(config)(view)[source]¶
Åsidosätter rubriken
Content-Security-Policyför den dekorerade vyn med direktiv i samma format som inställningenSECURE_CSP.Argumentet
configmåste vara en mappning med önskade CSP-direktiv. Omconfigär en tom mappning ({}) läggs ingen verkställande CSP-rubrik till i svaret från vyn, vilket i praktiken inaktiverar CSP för den vyn.Exempel:
from django.http import HttpResponse from django.utils.csp import CSP from django.views.decorators.csp import csp_override @csp_override( { "default-src": [CSP.SELF], "img-src": [CSP.SELF, "data:"], } ) def my_view(request): return HttpResponse("Custom Content-Security-Policy header applied") @csp_override({}) def my_other_view(request): return HttpResponse("No Content-Security-Policy header added")
- csp_report_only_override(config)(view)[source]¶
Åsidosätter rubriken
Content-Security-Policy-Report-Onlyför den dekorerade vyn med direktiv i samma format som inställningenSECURE_CSP_REPORT_ONLY.Precis som i
csp_override()måste argumentetconfigvara en mappning med önskade CSP-direktiv. Omconfigär en tom mappning ({}) läggs ingen CSP-rubrik för enbart rapportering till i svaret från vyn, vilket i praktiken inaktiverar rapporterings-CSP för den vyn.Exempel:
from django.http import HttpResponse from django.utils.csp import CSP from django.views.decorators.csp import csp_report_only_override @csp_report_only_override( { "default-src": [CSP.SELF], "img-src": [CSP.SELF, "data:"], "report-uri": "https://mysite.com/csp-report/", } ) def my_view(request): return HttpResponse("Custom Content-Security-Policy-Report-Only header applied") @csp_report_only_override({}) def my_other_view(request): return HttpResponse("No Content-Security-Policy-Report-Only header added")
Exemplen ovan förutsätter funktionsbaserade vyer. För klassbaserade vyer, se guiden för att dekorera klassbaserade vyer.
Användning av nonce¶
Ett CSP-nonce (”number used once”) är ett unikt, slumpmässigt värde som genereras per HTTP-svar. Django stöder noncer som ett säkert sätt att tillåta att specifika infogade <script>- eller <style>-element körs utan att förlita sig på 'unsafe-inline'.
Noncer aktiveras genom att inkludera den särskilda platshållaren NONCE i relevanta direktiv i dina CSP-inställningar, till exempel script-src eller style-src. När den finns skapar ContentSecurityPolicyMiddleware en nonce och infogar motsvarande källuttryck nonce-<value> i CSP-rubriken.
För att använda detta nonce i mallar behöver kontextprocessorn csp() aktiveras. Den lägger till variabeln csp_nonce i mallkontexten.
Malltaggen csp_nonce_attr lades till, med stöd för att återge Media-objekt.
För infogade <script>- och <style>-element inkluderas nonce direkt med kontextvariabeln:
<script nonce="{{ csp_nonce }}">
// This inline JavaScript will be allowed.
</script>
För externa elementen <script src="..."> och <link rel="stylesheet"> använder du malltaggen csp_nonce_attr:
<script src="/path/to/script.js" {% csp_nonce_attr %}></script>
<link rel="stylesheet" href="/path/to/style.css" {% csp_nonce_attr %}>
För att rendera resurserna i ett Media-objekt med nonce tillämpat skickar du objektet till malltaggen csp_nonce_attr:
{% csp_nonce_attr form.media %}
Webbläsaren kör endast infogade element som har ett attribut nonce=<value> som matchar värdet i rubriken Content-Security-Policy (eller Content-Security-Policy-Report-Only). Denna mekanism ger detaljerad kontroll över vilken infogad kod som tillåts köras.
Om en mall innehåller CSP-noncen men policyn inte innehåller NONCE kommer HTML-koden att innehålla ett nonce-attribut, men rubriken saknar det nödvändiga källuttrycket. I detta fall blockerar webbläsaren det infogade skriptet eller formatmallen (eller rapporterar det för konfigurationer med enbart rapportering).
Generering och cachning av nonce¶
Djangos nonce-generering är lat: mellanprogramvaran genererar endast ett nonce om {{ csp_nonce }} används vid mallrendering. Detta undviker onödigt arbete för sidor som inte använder noncer.
Eftersom noncer måste vara unika för varje begäran krävs dock extra försiktighet vid användning av helsidecache (till exempel Djangos cache-middleware eller CDN-cache). Att servera cachade svar med tidigare skapade noncer kan leda till återanvändning mellan användare och begäranden. Även om sådana svar fortfarande kan se ut att fungera (eftersom noncen i CSP-rubriken och HTML-innehållet matchar) motverkar återanvändning syftet med noncen och försvagar säkerheten.
För att säkerställa att nonce-baserade policyer förblir effektiva:
Undvik att cacha fullständiga svar som innehåller
{{ csp_nonce }}ellercsp_nonce_attr.Om cachning är nödvändig, använd en strategi som infogar ett nytt nonce vid varje begäran eller överväg att refaktorera programmet för att helt undvika infogade skript och stilar.