Bird
Raised Fist0
Djangoframework~10 mins

Content Security Policy in Django - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Content Security Policy
Browser sends request
Django server processes request
Django adds CSP header to response
Browser receives response
Browser checks CSP header
Browser allows or blocks resources based on CSP
Page renders with enforced security
The browser requests a page, Django adds a Content Security Policy header, and the browser enforces rules to allow or block resources.
Execution Sample
Django
from django.middleware.security import SecurityMiddleware

# Add CSP header in middleware
response['Content-Security-Policy'] = "default-src 'self'; script-src 'self' https://trusted.com"
This code adds a Content Security Policy header to responses to restrict resource loading.
Execution Table
StepActionCSP Header ValueBrowser BehaviorResult
1Browser sends request to Django serverN/AN/ARequest received by server
2Django processes request and prepares responseN/AN/AResponse ready to send
3Django adds CSP header to responsedefault-src 'self'; script-src 'self' https://trusted.comN/AResponse includes CSP header
4Browser receives response with CSP headerdefault-src 'self'; script-src 'self' https://trusted.comReads CSP rulesPrepares to enforce rules
5Browser loads page resourcesdefault-src 'self'; script-src 'self' https://trusted.comBlocks scripts from untrusted sourcesOnly trusted scripts run
6Page renders with enforced CSPdefault-src 'self'; script-src 'self' https://trusted.comPage secure from unauthorized scriptsSafe page display
7If script from untrusted source requesteddefault-src 'self'; script-src 'self' https://trusted.comBlocks script loadScript blocked, console error shown
8End of request-response cycleN/AN/ACycle complete
💡 Request-response cycle ends after browser enforces CSP rules on loaded resources
Variable Tracker
VariableStartAfter Step 3After Step 4Final
response['Content-Security-Policy']null"default-src 'self'; script-src 'self' https://trusted.com""default-src 'self'; script-src 'self' https://trusted.com""default-src 'self'; script-src 'self' https://trusted.com"
browser_allowed_scriptsAll sourcesN/AOnly 'self' and https://trusted.comOnly 'self' and https://trusted.com
Key Moments - 3 Insights
Why does the browser block some scripts even though the server sent the page?
Because the CSP header tells the browser to only allow scripts from trusted sources, as shown in execution_table step 5 where scripts from untrusted sources are blocked.
Can the CSP header be changed after the response is sent?
No, the CSP header is part of the HTTP response headers sent by Django before the browser receives the page, as shown in execution_table step 3 and 4.
What happens if the CSP header is missing?
The browser does not enforce any content restrictions, so all scripts and resources load freely, unlike the controlled behavior shown in steps 5 and 6.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 3. What value is assigned to the CSP header?
A"script-src 'none'"
B"img-src *"
C"default-src 'self'; script-src 'self' https://trusted.com"
DNo CSP header assigned
💡 Hint
Check the 'CSP Header Value' column at step 3 in the execution_table.
At which step does the browser start enforcing the CSP rules?
AStep 5
BStep 4
CStep 2
DStep 7
💡 Hint
Look at the 'Browser Behavior' column to see when scripts are blocked.
If the CSP header allowed scripts from any source, how would 'browser_allowed_scripts' change in variable_tracker?
AIt would remain 'Only self and https://trusted.com'
BIt would change to 'All sources'
CIt would be empty
DIt would cause an error
💡 Hint
Refer to the 'browser_allowed_scripts' row in variable_tracker and imagine no restrictions.
Concept Snapshot
Content Security Policy (CSP) is a security feature that tells browsers which sources are allowed to load content like scripts.
In Django, you add CSP headers to HTTP responses.
The browser reads these headers and blocks anything not allowed.
This helps prevent attacks like loading malicious scripts.
Always specify trusted sources clearly in your CSP header.
CSP headers are set before the response is sent to the browser.
Full Transcript
Content Security Policy (CSP) is a way to protect web pages by telling browsers which sources of content are safe. When a browser requests a page from a Django server, the server adds a CSP header to the response. This header lists trusted sources for scripts and other resources. When the browser receives the response, it reads the CSP header and blocks any scripts or resources not on the trusted list. This prevents harmful code from running on the page. The CSP header must be set before the response is sent. If the header is missing, the browser allows all content, which can be unsafe. Using CSP helps keep your web pages secure by controlling what content can load.

Practice

(1/5)
1. What is the main purpose of Content Security Policy (CSP) in a Django application?
easy
A. To handle database migrations automatically
B. To speed up the loading time of the website
C. To control which external resources can be loaded by the browser
D. To manage user authentication and sessions

Solution

  1. Step 1: Understand CSP's role in security

    CSP is designed to restrict what content the browser can load, preventing harmful scripts or resources.
  2. Step 2: Identify the correct purpose among options

    Only To control which external resources can be loaded by the browser describes controlling external resource loading, which matches CSP's function.
  3. Final Answer:

    To control which external resources can be loaded by the browser -> Option C
  4. Quick Check:

    CSP purpose = control resource loading [OK]
Hint: CSP controls resource loading to improve security [OK]
Common Mistakes:
  • Confusing CSP with performance optimization
  • Thinking CSP manages user sessions
  • Assuming CSP handles database tasks
2. Which of the following is the correct way to add a CSP header in a Django view?
easy
A. response.setHeader('Content-Security-Policy', "default-src 'self'")
B. response['headers']['Content-Security-Policy'] = "default-src 'self'"
C. response.set_header('Content-Security-Policy', "default-src 'self'")
D. response['Content-Security-Policy'] = "default-src 'self'"

Solution

  1. Step 1: Recall Django HttpResponse header syntax

    In Django, headers are set by assigning to response['Header-Name'].
  2. Step 2: Match the correct syntax

    response['Content-Security-Policy'] = "default-src 'self'" uses response['Content-Security-Policy'] = "default-src 'self'", which is correct Django syntax.
  3. Final Answer:

    response['Content-Security-Policy'] = "default-src 'self'" -> Option D
  4. Quick Check:

    Django header set = response['Header'] = value [OK]
Hint: Use response['Header-Name'] = value to set headers in Django [OK]
Common Mistakes:
  • Using JavaScript or Flask header syntax in Django
  • Calling non-existent methods like setHeader
  • Trying to set headers via response.headers dictionary
3. Given this Django middleware snippet, what CSP header will be sent in the response?
class CSPMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        response['Content-Security-Policy'] = "script-src 'self' https://cdn.example.com"
        return response
medium
A. Content-Security-Policy: default-src 'self'
B. Content-Security-Policy: script-src 'self' https://cdn.example.com
C. No Content-Security-Policy header is set
D. Content-Security-Policy: script-src 'none'

Solution

  1. Step 1: Analyze the middleware code

    The middleware sets response['Content-Security-Policy'] to "script-src 'self' https://cdn.example.com" before returning the response.
  2. Step 2: Determine the header sent

    The header sent will exactly match the assigned string in the middleware.
  3. Final Answer:

    Content-Security-Policy: script-src 'self' https://cdn.example.com -> Option B
  4. Quick Check:

    Middleware sets CSP header = script-src 'self' https://cdn.example.com [OK]
Hint: Middleware sets header exactly as assigned before returning response [OK]
Common Mistakes:
  • Assuming default-src is set instead of script-src
  • Thinking header is not set because of missing return
  • Confusing middleware with view-level headers
4. You added this CSP header in Django but your inline scripts stopped working:
response['Content-Security-Policy'] = "default-src 'self'"
What is the likely cause and fix?
medium
A. Inline scripts blocked; add 'unsafe-inline' to script-src directive
B. Header syntax error; remove quotes around 'self'
C. Missing HTTPS; change 'self' to https://self
D. No fix needed; inline scripts should work by default

Solution

  1. Step 1: Understand CSP default-src effect on scripts

    default-src 'self' blocks inline scripts by default because inline scripts are unsafe.
  2. Step 2: Fix by allowing inline scripts explicitly

    Adding 'unsafe-inline' to script-src directive allows inline scripts to run.
  3. Final Answer:

    Inline scripts blocked; add 'unsafe-inline' to script-src directive -> Option A
  4. Quick Check:

    Inline scripts need 'unsafe-inline' in CSP [OK]
Hint: Add 'unsafe-inline' to allow inline scripts in CSP [OK]
Common Mistakes:
  • Removing quotes around 'self' breaks CSP syntax
  • Changing 'self' to https://self is invalid
  • Assuming inline scripts work without explicit permission
5. You want to allow images from your own site and from https://images.example.com but block all other sources. Which CSP header directive is correct in Django?
hard
A. response['Content-Security-Policy'] = "img-src 'self' https://images.example.com; default-src 'none'"
B. response['Content-Security-Policy'] = "default-src 'self' https://images.example.com"
C. response['Content-Security-Policy'] = "img-src *; default-src 'self'"
D. response['Content-Security-Policy'] = "img-src 'none'; default-src https://images.example.com"

Solution

  1. Step 1: Identify directives to allow images only from specific sources

    img-src directive controls image sources; 'self' allows own site, plus https://images.example.com.
  2. Step 2: Block all other sources by setting default-src to 'none'

    default-src 'none' blocks everything else not explicitly allowed.
  3. Final Answer:

    response['Content-Security-Policy'] = "img-src 'self' https://images.example.com; default-src 'none'" -> Option A
  4. Quick Check:

    Allow images from self and example.com, block others [OK]
Hint: Use img-src for images and default-src 'none' to block others [OK]
Common Mistakes:
  • Using default-src for images allows too many sources
  • Using img-src * allows all images, not secure
  • Setting img-src 'none' blocks all images