Bird
Raised Fist0
Djangoframework~10 mins

XSS prevention in templates 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 - XSS prevention in templates
User Input Received
Template Rendering Begins
Escape Special Characters?
NoRaw Output (Unsafe)
Yes
Safe HTML Output Rendered
Browser Displays Content Safely
This flow shows how Django templates handle user input by escaping special characters to prevent unsafe HTML and scripts from running.
Execution Sample
Django
{% autoescape on %}
Hello, {{ user_input }}!
{% endautoescape %}
This template safely outputs user input by escaping HTML special characters to prevent XSS.
Execution Table
StepTemplate PartInput ValueEscape AppliedOutput Rendered
1Start Renderinguser_input = '<script>alert(1)</script>'N/AN/A
2Evaluate {{ user_input }}<script>alert(1)</script>Yes&lt;script&gt;alert(1)&lt;/script&gt;
3Render Full TemplateN/AN/AHello, &lt;script&gt;alert(1)&lt;/script&gt;!
💡 Template rendering completes with escaped user input to prevent XSS.
Variable Tracker
VariableStartAfter EscapeFinal Output
user_input<script>alert(1)</script>&lt;script&gt;alert(1)&lt;/script&gt;&lt;script&gt;alert(1)&lt;/script&gt;
Key Moments - 2 Insights
Why does the output show &lt;script&gt; instead of <script>?
Because Django escapes special HTML characters like < and > to &lt; and &gt; to prevent the browser from running scripts, as shown in step 2 of the execution table.
What happens if autoescape is turned off?
If autoescape is off, the raw input is rendered without escaping, which can allow scripts to run and cause XSS, unlike the safe output in step 3.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the output rendered at step 2?
A&lt;script&gt;alert(1)&lt;/script&gt;
B<script>alert(1)</script>
Calert(1)
DHello, user!
💡 Hint
Check the 'Output Rendered' column at step 2 in the execution_table.
At which step does Django apply escaping to user input?
AStep 1
BStep 3
CStep 2
DNo escaping applied
💡 Hint
Look at the 'Escape Applied' column in the execution_table.
If autoescape was off, how would the final output change?
AIt would show escaped characters like &lt; and &gt;
BIt would render raw HTML including <script> tags
CIt would remove the user input entirely
DIt would show an error
💡 Hint
Refer to the key_moments section about autoescape effects.
Concept Snapshot
Django templates escape user input by default to prevent XSS.
Use {{ variable }} inside {% autoescape on %} blocks.
Special characters like <, >, & become &lt;, &gt;, &amp;.
Turning off autoescape renders raw HTML, which is unsafe.
Always trust Django's escaping for safe output.
Full Transcript
This visual execution shows how Django templates prevent cross-site scripting (XSS) by escaping special HTML characters in user input. When rendering a template with user input like '<script>alert(1)</script>', Django replaces < and > with &lt; and &gt; to stop the browser from running scripts. The execution table traces each step: starting with the raw input, applying escaping during template evaluation, and rendering the safe output. The variable tracker shows how the user_input variable changes from raw to escaped form. Key moments clarify why escaping is necessary and what happens if autoescape is turned off. The quiz tests understanding of when escaping happens and how output changes. This ensures beginners see exactly how Django keeps templates safe from XSS attacks.

Practice

(1/5)
1. What does Django do by default to protect against XSS attacks when rendering variables in templates?
easy
A. It disables rendering of any user input.
B. It automatically escapes variables to prevent malicious code execution.
C. It requires manual escaping of variables in every template.
D. It converts all variables to uppercase before rendering.

Solution

  1. Step 1: Understand Django's default template behavior

    Django templates automatically escape variables to prevent malicious scripts from running in the browser.
  2. Step 2: Compare options with this behavior

    Only It automatically escapes variables to prevent malicious code execution. correctly states this automatic escaping feature, while others describe incorrect or unrelated behaviors.
  3. Final Answer:

    It automatically escapes variables to prevent malicious code execution. -> Option B
  4. Quick Check:

    Default escaping = It automatically escapes variables to prevent malicious code execution. [OK]
Hint: Remember: Django escapes variables automatically unless told otherwise [OK]
Common Mistakes:
  • Thinking you must manually escape variables always
  • Believing Django disables user input rendering
  • Assuming variables are transformed instead of escaped
2. Which of the following is the correct way to mark a variable as safe (not escaped) in a Django template?
easy
A. {{ variable|escape }}
B. {{ variable|strip }}
C. {{ variable|safe }}
D. {{ variable|clean }}

Solution

  1. Step 1: Identify the filter that marks content safe

    The safe filter tells Django not to escape the variable, rendering HTML as-is.
  2. Step 2: Check other filters

    escape escapes content, strip and clean are not standard Django filters for safety.
  3. Final Answer:

    {{ variable|safe }} -> Option C
  4. Quick Check:

    Use safe filter to disable escaping = {{ variable|safe }} [OK]
Hint: Use '|safe' to show trusted HTML without escaping [OK]
Common Mistakes:
  • Using '|escape' which does the opposite
  • Confusing '|strip' or '|clean' as safety filters
  • Forgetting to mark trusted content safe explicitly
3. Given the template code:
{{ user_input }}

and the user input is <script>alert('XSS')</script>, what will be rendered in the browser?
medium
A. <script>alert('XSS')</script> shown as text
B. executed as script
C. An error message about unsafe content
D. Nothing will be shown

Solution

  1. Step 1: Understand default escaping of variables

    Django escapes user input by default, so HTML tags are shown as text, not executed.
  2. Step 2: Apply this to the given input

    The script tags will be converted to safe text entities and displayed literally.
  3. Final Answer:

    <script>alert('XSS')</script> shown as text -> Option A
  4. Quick Check:

    Escaped input shows tags as text = <script>alert('XSS')</script> shown as text [OK]
Hint: Default escape shows tags as text, not scripts [OK]
Common Mistakes:
  • Thinking the script runs automatically
  • Expecting an error instead of safe output
  • Assuming nothing is shown for unsafe input
4. You see this template code:
{{ comment|safe }}

but users report XSS attacks. What is the likely problem?
medium
A. The template engine is disabled.
B. The escape filter is missing.
C. The template variable is not wrapped in quotes.
D. The safe filter is used on untrusted user input.

Solution

  1. Step 1: Analyze the use of the safe filter

    Using safe on user input disables escaping, allowing scripts to run if input is malicious.
  2. Step 2: Identify the cause of XSS

    Applying safe to untrusted input is unsafe and causes XSS vulnerabilities.
  3. Final Answer:

    The safe filter is used on untrusted user input. -> Option D
  4. Quick Check:

    Unsafe use of safe filter = The safe filter is used on untrusted user input. [OK]
Hint: Never use '|safe' on untrusted user input [OK]
Common Mistakes:
  • Assuming escape filter fixes safe misuse
  • Thinking quotes affect XSS protection
  • Believing template engine disables XSS automatically
5. You want to display user comments that may contain safe HTML tags like <b> and <i>, but prevent scripts. Which approach best prevents XSS while allowing these tags?
hard
A. Sanitize the comment in the backend to allow only safe tags, then use {{ comment|safe }}.
B. Use {{ comment|safe }} directly in the template.
C. Escape the comment with {{ comment|escape }} and then use |safe.
D. Store comments as plain text and never allow any HTML tags.

Solution

  1. Step 1: Understand the need to allow some HTML safely

    Allowing safe tags requires cleaning input to remove dangerous scripts but keep allowed tags.
  2. Step 2: Choose the correct method

    Sanitizing backend input to whitelist safe tags then marking safe in template is the secure way.
  3. Step 3: Evaluate other options

    Using {{ comment|safe }} directly risks XSS by trusting raw input; combining |escape and |safe misuses filters; disallowing all HTML prevents desired formatting.
  4. Final Answer:

    Sanitize the comment in the backend to allow only safe tags, then use {{ comment|safe }}. -> Option A
  5. Quick Check:

    Backend sanitize + safe filter = Sanitize the comment in the backend to allow only safe tags, then use {{ comment|safe }}. [OK]
Hint: Clean input backend, then mark safe in template [OK]
Common Mistakes:
  • Trusting raw user input with safe filter
  • Misusing escape and safe filters together
  • Disallowing all HTML when some is needed