Crlf Injection with Hmac Signatures
How Crlf Injection Manifests in Hmac Signatures
CRLF injection in HMAC signature implementations typically occurs when user-controlled data flows through HTTP headers that form part of the signing process. The vulnerability arises because HMAC implementations often include HTTP headers in the signature base string, creating an attack surface if those headers aren't properly validated.
The most common manifestation involves the Date header, which many HMAC implementations include in the signature base string. An attacker can inject additional headers by manipulating the Date value:
POST /api/v1/resource HTTP/1.1
Host: example.com
Date: Fri, 01 Jan 2021 00:00:00 GMT
Content-Type: application/json
{ "data": "value" }If the Date header value contains CRLF sequences, an attacker can inject arbitrary headers that become part of the signed message:
Date: Fri, 01 Jan 2021 00:00:00 GMT
Content-Type: application/json
X-Injected-Header: malicious-valueThis creates several attack vectors specific to HMAC signatures:
- Header injection: Additional headers bypass validation if the signature includes them
- Signature bypass: Attackers can manipulate the signed content without detection
- Request smuggling: CRLF injection can alter how requests are parsed by backend services
Another HMAC-specific scenario involves the Authorization header itself. Many HMAC implementations parse the Authorization header to extract signature parameters. If this parsing is naive, CRLF injection can break the header structure:
Authorization: HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20210101/us-east-1/iam/aws4_request
X-Malicious: injected-valueThe signature verification process then operates on a modified message, potentially validating a request the server never intended to process.
Content-Type header manipulation presents another HMAC-specific risk. Since the Content-Type often appears in the signature base string, an attacker can inject additional content types or modify the declared media type:
Content-Type: application/json
X-Injected: valueThis can cause the server to parse the request body differently than expected, potentially bypassing content validation or triggering unexpected processing paths.
HMAC Signatures-Specific Detection
Detecting CRLF injection in HMAC implementations requires examining both the signature generation and verification code paths. The key is identifying where user input flows into HTTP headers that become part of the signature base string.
Static analysis should focus on these HMAC-specific patterns:
# Vulnerable pattern - direct header concatenationdef generate_signature(request): base_string = f"{request.method}\n{request.path}\n{request.headers['Date']}\n{request.headers['Content-Type']}" return hmac.new(key, base_string.encode(), hashlib.sha256).hexdigest()The vulnerability here is that request.headers['Date'] and request.headers['Content-Type'] are inserted directly into the base string without validation. Any CRLF sequences in these values will be preserved.
Dynamic testing should include:
- Submitting requests with
%0D%0Asequences in Date headers - Testing Authorization header parsing with malformed values
- Verifying Content-Type header validation
middleBrick's API security scanner specifically tests for HMAC-related CRLF injection through these black-box techniques:
POST /api/v1/endpoint HTTP/1.1
Host: target.com
Date: Mon, 01 Jan 2021 00:00:00 GMT%0D%0AX-Injected: malicious
Content-Type: application/json
Authorization: HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20210101/us-east-1/iam/aws4_request,Signature=abcd1234
{ "data": "test" }The scanner verifies whether injected headers affect signature validation or request processing. It also tests for request smuggling by varying the injection patterns and observing server responses.
Runtime monitoring should watch for:
- Unexpected header values in processed requests
- Signature verification failures that correlate with header manipulation
- Content-Type mismatches between declared and actual content
HMAC Signatures-Specific Remediation
Remediating CRLF injection in HMAC implementations requires input validation at the boundaries where user data enters the signing process. The most effective approach combines strict header validation with safe string construction.
Header validation should use regex patterns that reject CRLF sequences:
import reimport hmacimport hashlibfrom datetime import datetime# RFC 7231 compliant Date header validationdef validate_date_header(date_str): # Must match RFC 1123 format without CRLF pattern = r'^[A-Za-z]{3}, [0-9]{2} [A-Za-z]{3} [0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2} GMT$' if not re.match(pattern, date_str): raise ValueError('Invalid Date header format') return date_str# Safe HMAC signature generationdef generate_hmac_signature(request, secret_key): # Validate headers before use date_header = validate_date_header(request.headers.get('Date', '')) content_type = request.headers.get('Content-Type', '') # Build base string safely base_string = f"{request.method}\n{request.path}\n{date_header}\n{content_type}" # Compute HMAC return hmac.new(secret_key.encode(), base_string.encode(), hashlib.sha256).hexdigest()For Authorization header parsing, use strict tokenization:
def parse_authorization_header(header): if not header.startswith('HMAC-SHA256 '): raise ValueError('Invalid authorization scheme') # Split on commas, not on CRLF parts = header.split(',') params = {} for part in parts: if '=' in part: key, value = part.split('=', 1) params[key.strip()] = value.strip() return paramsContent-Type validation should enforce strict MIME type patterns:
def validate_content_type(content_type): # Only allow basic MIME types without parameters pattern = r'^[a-z-]+/[a-z0-9-]+(?:;[a-z-]+=[a-z0-9-]+)*$' if not re.match(pattern, content_type): raise ValueError('Invalid Content-Type') return content_typeAdditional defenses include:
- Canonicalization of header values before signing
- Length limits on all header values
- Whitelisting allowed header names
- Using structured formats (JSON) instead of concatenated strings where possible
middleBrick's CLI tool can help verify these fixes:
middlebrick scan https://api.example.com/v1/resource
--test-crlf-injection
--hmac-signature-analysisThis scans for remaining CRLF injection vectors and verifies that HMAC implementations properly validate header inputs.
Frequently Asked Questions
Why is CRLF injection particularly dangerous for HMAC signatures?
How can I test if my HMAC implementation is vulnerable to CRLF injection?
%0D%0A sequences in headers that your HMAC implementation uses for signing. Use middleBrick's API security scanner which automatically tests for HMAC-specific CRLF injection by injecting malicious headers and verifying if they affect signature validation or request processing. The scanner also tests for request smuggling vulnerabilities that CRLF injection can enable.