Content Security PolicyLink to this heading

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.

ÖversiktLink to this heading

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ällningarLink to this heading

Klassen ContentSecurityPolicyMiddleware konfigureras med följande inställningar:

Rapporter om policyöverträdelserLink to this heading

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ädelse­rapporter. 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-konstanterLink to this heading

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 CSPLink to this definition

Uppräkning som tillhandahåller standardiserade konstanter för vanliga CSP-källuttryck.

NONELink to this definition

Representerar 'none'. Blockerar inläsning av resurser för det angivna direktivet.

REPORT_SAMPLELink to this definition

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.

SELFLink to this definition

Representerar 'self'. Tillåter att resurser laddas från samma ursprung (samma schema, värd och port).

STRICT_DYNAMICLink to this definition

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_EVALLink to this definition

Representerar 'unsafe-eval'. Tillåter användning av eval() och liknande JavaScript-funktioner. Starkt avrått.

UNSAFE_HASHESLink to this definition

Representerar 'unsafe-hashes'. Tillåter infogade händelsehanterare och vissa javascript:-URI:er när deras innehållshashar matchar en policyregel. Kräver CSP nivå 3 eller senare.

UNSAFE_INLINELink to this definition

Representerar 'unsafe-inline'. Tillåter körning av infogade skript, stilar och javascript:-URL:er. Generellt avrått, särskilt för skript.

WASM_UNSAFE_EVALLink to this definition

Representerar 'wasm-unsafe-eval'. Tillåter kompilering och körning av WebAssembly-kod utan att aktivera 'unsafe-eval' för skript.

NONCELink to this definition

Django-specifikt platshållarvärde ("<CSP_NONCE_SENTINEL>") som används i direktiven script-src eller style-src för att aktivera nonce-baserad CSP. Strängen ersätts vid körning av ContentSecurityPolicyMiddleware med en säker slumpmässig nonce som skapas för varje begäran. Se den detaljerade förklaringen i Användning av nonce.

DekoratörerLink to this heading

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.

csp_override(config)(view)Link to this definition

Åsidosätter rubriken Content-Security-Policy för den dekorerade vyn med direktiv i samma format som inställningen SECURE_CSP.

Argumentet config måste vara en mappning med önskade CSP-direktiv. Om config ä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:

Code
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)Link to this definition

Åsidosätter rubriken Content-Security-Policy-Report-Only för den dekorerade vyn med direktiv i samma format som inställningen SECURE_CSP_REPORT_ONLY.

Precis som i csp_override() måste argumentet config vara en mappning med önskade CSP-direktiv. Om config ä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:

Code
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 nonceLink to this heading

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.

För infogade <script>- och <style>-element inkluderas nonce direkt med kontextvariabeln:

Django template
<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:

Django template
<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:

Django template
{% 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 nonceLink to this heading

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 }} eller csp_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.