Phishing Api Keys in Django with Hmac Signatures
Phishing API Keys in Django with HMAC Signatures — How This Combination Creates or Exposes the Vulnerability
Phishing API keys in Django when HMAC signatures are used for request authentication occurs when a client embeds a long-term secret into a frontend or mobile client and uses it to sign requests. If the signing key is exposed via source code repositories, browser inspection, or social engineering, an attacker can collect both the key and a valid signature (e.g., from logs or replayed requests). This combination creates a phishing surface: the attacker can reuse the key and a captured signature to forge authenticated requests to your Django backend, bypassing intended integrity checks.
In Django, a typical pattern uses a shared secret to generate an HMAC over a canonical string (e.g., timestamp + payload). If the server only verifies the HMAC without also validating request freshness and replay context, a phished signature remains valid until the key is rotated. Additionally, if the API key is transmitted in headers or query parameters over non-TLS channels, interception further amplifies risk. Attackers may also target developer workflows (e.g., debugging endpoints or management commands) that inadvertently expose signing keys or signatures, completing the phishing chain.
Real-world examples include leaked GitHub tokens that are also used as HMAC secrets, or JavaScript frontends that embed a key to sign AJAX requests. In such cases, the signature itself becomes reusable, and without protections like one-time nonces or short-lived timestamps, a captured request can be replayed. The OWASP API Top 10 category 2023-A07: Identification and Authentication Failures maps to this risk, as improper binding between secrets, signatures, and session context weakens authentication.
middleBrick scans can detect scenarios where API keys appear in client-side contexts or where endpoints accept HMAC-signed requests without adequate replay protection. By correlating OpenAPI/Swagger specs (with full $ref resolution) against runtime behavior, the scanner highlights authentication and integrity gaps, including missing timestamp validation and unsafe consumption patterns. Findings include severity, contextual guidance, and references to frameworks such as PCI-DSS and SOC2 where relevant.
For continuous assurance, the Pro plan enables scheduled scans and alerts, while the CLI allows you to script checks from the terminal. Remember: middleBrick detects and reports these issues; it does not fix, patch, block, or remediate.
HMAC Signatures-Specific Remediation in Django — Concrete Code Fixes
To remediate phishing risks with HMAC signatures in Django, enforce strict canonicalization, short validity windows, replay protection, and secure key management. Below are concrete, working examples that you can adopt in your Django views.
1. Canonical String and HMAC Verification
Define a deterministic method to build the string to sign. Include the HTTP method, content-type, timestamp, and a stable representation of the payload. Use constant-time comparison to avoid timing attacks.
import hmac
import hashlib
def verify_hmac(request):
timestamp = request.META.get('HTTP_X_REQUEST_TIMESTAMP')
signature = request.META.get('HTTP_X_SIGNATURE')
if not timestamp or not signature:
return False
# Reject requests older than 30 seconds to prevent replay
if abs(time.time() - int(timestamp)) > 30:
return False
# Build canonical string
body = request.body.decode('utf-8') if request.body else ''
to_sign = f'POST\napplication/json\n{timestamp}\n{body}'
expected = hmac.new(
settings.HMAC_SECRET.encode('utf-8'),
to_sign.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
2. Middleware for Replay Cache
Use a short-lived cache (e.g., Django cache framework with Redis) to store recently seen timestamp+hash tuples and reject duplicates.
from django.core.cache import cache
def check_replay(timestamp, fingerprint):
key = f'hmac_replay:{fingerprint}'
if cache.get(key):
return False # Replay detected
cache.set(key, True, timeout=35) # slightly longer than request window
return True
3. View Integration
Combine verification and replay checks in your view, returning 401 for invalid requests.
import time
from django.http import JsonResponse, HttpResponseForbidden
def my_protected_view(request):
if not verify_hmac(request):
return HttpResponseForbidden('Invalid signature or timestamp')
fingerprint = f'{request.META[\"HTTP_X_TIMESTAMP\"]}:{hashlib.sha256(request.body).hexdigest()}'
if not check_replay(request.META['HTTP_X_TIMESTAMP'], fingerprint):
return HttpResponseForbidden('Replay detected')
# Proceed with business logic
return JsonResponse({'status': 'ok'})
4. Secure Key Storage
Never embed HMAC secrets in frontend code or client-side JavaScript. Store secrets in environment variables and reference them via settings.HMAC_SECRET. Rotate keys periodically and monitor for leakage using scanning tools that integrate with CI/CD pipelines.
These steps align with OWASP recommendations for authentication integrity and help mitigate phishing scenarios where API keys and signatures are harvested. Integrate these patterns into your Django project and complement them with automated scans to detect misconfigurations early.
middleBrick’s CLI and GitHub Action can be used to validate that endpoints requiring HMAC enforce timestamp and replay checks; the MCP Server enables rapid scanning from AI coding assistants. The Dashboard helps you track security scores over time, while the Free tier supports initial exploration.