Mitigation Strategy: Autoescaping
Description:
- Configuration: Modify the Jinja2
Environment
initialization to enable autoescaping by default. This is done where the Jinja2 environment is created. - Code Modification:
from jinja2 import Environment, FileSystemLoader, select_autoescape env = Environment( loader=FileSystemLoader('templates'), # Path to your templates autoescape=select_autoescape(['html', 'htm', 'xml']) # Autoescape HTML and XML ) # OR, for simpler cases: # env = Environment(loader=FileSystemLoader('templates'), autoescape=True)
- Verification: After enabling, test with malicious input (e.g.,
<script>alert('XSS')</script>
) in variables. Verify the rendered output contains escaped equivalents (e.g.,<script>alert('XSS')</script>
). - Ongoing Monitoring: Regularly review template rendering and ensure autoescaping isn't accidentally disabled.
-
Threats Mitigated:
- Cross-Site Scripting (XSS) (Severity: High): Prevents injected JavaScript from executing.
- HTML Injection (Severity: Medium): Prevents injecting arbitrary HTML tags.
- Template Injection (Severity: High): Reduces the attack surface by preventing common injection forms.
-
Impact:
- XSS: Risk reduction: Very High.
- HTML Injection: Risk reduction: Very High.
- Template Injection: Risk reduction: High.
-
Currently Implemented:
- Example:
app/config.py
(Jinja2 environment initialization). - Example: All templates in
templates/
are autoescaped.
- Example:
-
Missing Implementation:
- Example: Verify email templates (
templates/email/
) are also autoescaped. - Example: Check custom template loaders for bypassing autoescaping.
- Example: Verify email templates (
Mitigation Strategy: Explicitly Marking Safe Content
Description:
- Identify Safe Content: Carefully analyze instances where you render non-user-provided, known-safe HTML.
- Use
MarkupSafe
: Wrap safe HTML withMarkupSafe
before passing it to the template context.from markupsafe import Markup safe_html = Markup("<strong>This is safe HTML.</strong>") context = {'safe_content': safe_html} # Pass 'context' to the template
- Use
|safe
Filter (Sparingly): In the template, use|safe
only on variables marked as safe withMarkupSafe
or rigorously validated.{{ safe_content | safe }}
- Document Justification: For every use of
|safe
orMarkupSafe
, add a comment explaining why it's safe. - Avoid Overuse: Minimize
|safe
use. Each instance increases risk if content isn't truly safe.
-
Threats Mitigated:
- XSS (Severity: High): Incorrect
|safe
use can introduce XSS. Correct use avoids this. - HTML Injection (Severity: Medium): Similar to XSS, incorrect use introduces vulnerabilities.
- XSS (Severity: High): Incorrect
-
Impact:
- XSS: Risk reduction: Neutral (correct use) / Risk increase: Very High (incorrect use).
- HTML Injection: Risk reduction: Neutral (correct use) / Risk increase: High (incorrect use).
-
Currently Implemented:
- Example:
app/utils.py
(generate_safe_banner
) usesMarkupSafe
. - Example:
templates/home.html
uses{{ banner | safe }}
.
- Example:
-
Missing Implementation:
- Example: Review all
|safe
uses forMarkupSafe
or strong justification. - Example: Check for user-provided data accidentally marked as safe.
- Example: Review all
Mitigation Strategy: Sandboxing (For Untrusted Templates)
Description:
- Identify Untrusted Templates: Determine if users can upload or create templates (untrusted).
- Use
SandboxedEnvironment
: Create a separate Jinja2 environment usingSandboxedEnvironment
for untrusted templates.from jinja2 import SandboxedEnvironment, FileSystemLoader sandboxed_env = SandboxedEnvironment(loader=FileSystemLoader('untrusted_templates'))
- Load Untrusted Templates: Use
sandboxed_env
to load and render from the untrusted source.template = sandboxed_env.from_string(untrusted_template_string) rendered_output = template.render(context)
- Configure Restrictions: Review and customize
SandboxedEnvironment
restrictions if needed. - Testing: Thoroughly test with malicious template inputs.
-
Threats Mitigated:
- Remote Code Execution (RCE) (Severity: Critical): Prevents access to Python built-ins and dangerous functions.
- Information Disclosure (Severity: High): Restricts access to sensitive attributes/methods.
- Template Injection (Severity: High): Strong defense against template injection.
-
Impact:
- RCE: Risk reduction: Very High.
- Information Disclosure: Risk reduction: High.
- Template Injection: Risk reduction: High.
-
Currently Implemented:
- Example:
app/views/user_templates.py
usesSandboxedEnvironment
.
- Example:
-
Missing Implementation:
- Example: Migrate any other untrusted template rendering to
SandboxedEnvironment
.
- Example: Migrate any other untrusted template rendering to
Mitigation Strategy: Template Design Best Practices (Jinja2 Specific)
Description:
- Minimize Logic: Keep templates focused on presentation. Avoid complex logic in templates. Do it in application code.
- Use Template Inheritance: Create a base template (
base.html
) with common elements. Use{% extends %}
and{% block %}
. - Separate Data and Presentation: Clearly separate data (context) from presentation logic.
- Use Included Templates: For reusable snippets, use
{% include %}
. - Avoid Dynamic Includes: Crucially, avoid using variables to determine which template to include (e.g.,
{% include user_selected_template %}
). This is a major Jinja2-specific risk.
-
Threats Mitigated:
- Template Injection (Severity: High): Simplifying templates and avoiding dynamic includes reduces the attack surface.
- Information Disclosure (Severity: Medium): Avoiding complex logic reduces accidental exposure.
-
Impact:
- Template Injection: Risk reduction: Medium (especially avoiding dynamic includes).
- Information Disclosure: Risk reduction: Low.
-
Currently Implemented:
- Example:
templates/base.html
is the base template. - Example: Templates use
{% extends 'base.html' %}
.
- Example:
-
Missing Implementation:
- Example: Refactor old templates with excessive logic.
- Example: Ensure consistent inheritance.
- Example: Remove any dynamic includes. This is the most important part of this strategy.
Mitigation Strategy: Avoid eval
and exec
like functionality within Custom Filters/Functions
Description:
- Review Custom Filters and Functions: Examine any custom Jinja2 filters or functions. Ensure none dynamically execute code based on user input.
- Avoid Dynamic Code Generation: Do not create filters/functions that take user input to construct and execute Python code.
- Use Safe Alternatives: Use Jinja2's built-in filters and tests for common tasks.
- Sandboxing (If Absolutely Necessary): If you must use dynamic code execution, heavily restrict and sandbox it. Use an isolated environment. Thoroughly validate input. Highly discouraged.
- Documentation and Review: Document custom filters/functions, stating purpose and security. Regularly review.
-
Threats Mitigated:
- Remote Code Execution (RCE) (Severity: Critical): Prevents injecting and executing arbitrary Python.
- Template Injection (Severity: High): Reduces the attack surface.
-
Impact:
- RCE: Risk reduction: Very High.
- Template Injection: Risk reduction: High.
-
Currently Implemented:
- Example: Code review guidelines prohibit
eval
/exec
in custom Jinja2 components.
- Example: Code review guidelines prohibit
-
Missing Implementation:
- Example: Thoroughly review existing custom filters/functions.
- Example: Implement automated checks for
eval
/exec
.