HIGH server side template injectiondjangohmac signatures

Server Side Template Injection in Django with Hmac Signatures

Server Side Template Injection in Django with Hmac Signatures — how this specific combination creates or exposes the vulnerability

Server Side Template Injection (SSTI) in Django arises when an attacker can control a value that is later rendered by a template engine and can invoke arbitrary template logic. Django’s built-in autoescape and sandbox reduce risk, but certain integrations—such as using Hmac Signatures in template context—can inadvertently expose dangerous pathways if user input influences which template tags or filters are invoked.

Consider a scenario where a Django view builds a template context from an HTTP query parameter and then renders a template that includes an Hmac signature for integrity verification. If the parameter is used both to influence template selection or variable names and to compute or validate an Hmac, an attacker may supply crafted input that leads to template code execution. For example, using the with tag together with dictionary lookup patterns can allow an attacker to reach otherwise restricted objects if the dictionary keys are derived from user-controlled data.

Django templates are not a full programming language, but they support filters, tags, and custom template tags that can interact with Python objects. When Hmac signatures are generated in Python (e.g., using hmac.new) and then compared inside templates, or when a signature is used to authorize inclusion of a template fragment, improper validation or reflection can turn the signature check into an injection aid. An attacker might try to break out of a value context and invoke arbitrary template logic by supplying payloads that leverage template filters or by nesting unsafe includes that reference attacker-chosen template variables linked to the Hmac flow.

In combination with OpenAPI/Swagger spec analysis, tools like middleBrick can detect dangerous patterns where Hmac verification logic and template rendering share mutable context. For instance, if a signature is computed over a subset of parameters but the template includes dynamic blocks whose presence depends on parameters not covered by the Hmac, the mismatch can lead to insecure direct object references or template injection. middleBrick runs checks such as Input Validation and Property Authorization in parallel to highlight these cross-cutting risks without requiring credentials.

Real-world patterns to watch for include:

  • Using request.GET or request.POST values to build dictionary keys that are later used in {% with %} or {{ variable|safe }}.
  • Embedding Hmac verification inside templates via custom filters that accept user data and compare signatures, potentially allowing an attacker to probe valid signature formats.
  • Including templates conditionally based on parameters that should have been protected by the Hmac but are instead reflected in the rendered output.

middleBrick’s LLM/AI Security checks are not relevant to classic SSTI, but its Inventory Management and Input Validation tests can surface risky template usage patterns that intersect with Hmac workflows.

Hmac Signatures-Specific Remediation in Django — concrete code fixes

Remediation focuses on strict separation of trusted signing logic and template rendering, avoiding any direct reflection of user input into template execution paths. Always compute and compare Hmac in Python code, and pass only safe, minimal values to templates.

Example of a safe Hmac generation and verification flow in Django views:

import hmac
import hashlib
from django.http import HttpResponse
from django.template import loader

def generate_hmac(data: str, secret: bytes) -> str:
    return hmac.new(secret, data.encode('utf-8'), hashlib.sha256).hexdigest()

def verify_hmac(data: str, received_sig: str, secret: bytes) -> bool:
    expected_sig = generate_hmac(data, secret)
    return hmac.compare_digest(expected_sig, received_sig)

def my_view(request):
    secret = b'super-secret-key'
    user_id = request.GET.get('user_id', '')
    # Validate format before use
    if not user_id.isalnum():
        return HttpResponse('Invalid input', status=400)
    data_to_sign = f'user:{user_id}'
    signature = generate_hmac(data_to_sign, secret)
    template = loader.get_template('my_template.html')
    context = {
        'user_id': user_id,
        'signature': signature,
    }
    return HttpResponse(template.render(context, request))

In the template (my_template.html), avoid using {{ signature|safe }} unless you are certain the signature is not user-controlled markup. Prefer autoescaped output:

<div data-signature="{{ signature }}">User ID: {{ user_id }}</div>

When using Hmac to authorize template fragments, validate the signature before selecting which template block to render:

def fragment_view(request):
    secret = b'super-secret-key'
    user_id = request.GET.get('user_id', '')
    received_sig = request.GET.get('sig', '')
    if not user_id.isalnum() or not verify_hmac(f'user:{user_id}', received_sig, secret):
        return HttpResponse('Forbidden', status=403)
    # Only after verification, choose a safe template
    template_name = 'fragment_user.html'  # static, not derived from user input
    template = loader.get_template(template_name)
    return HttpResponse(template.render({'user_id': user_id}, request))

Additional best practices:

  • Never construct template names or variable names directly from user input, even if covered by an Hmac.
  • Use Django’s template filters for escaping and avoid the safe filter unless absolutely necessary and the content is strictly trusted.
  • Leverage Django’s built-in CSRF protections and ensure Hmac keys are stored securely, not in source code.
  • For sensitive operations, combine Hmac with session-based authentication and principle of least privilege.

middleBrick’s Pro plan can integrate these checks into CI/CD pipelines, adding API security scans on a configurable schedule so shifts-left detection of risky patterns is possible without manual review.

Frequently Asked Questions

Can an Hmac signature prevent SSTI if the template includes user-controlled variables?
No. Hmac signatures ensure integrity and authenticity of data, but they do not prevent template injection. If user input is reflected into template logic or variable names, SSTI can still occur. Always validate and sanitize input and avoid dynamic template constructs.
Is it safe to output Hmac signatures with the |safe filter in Django templates?
Generally no. Use the |safe filter only if the signature is guaranteed not to contain user-controlled markup. Prefer autoescaped output to prevent accidental injection via reflected values.