Cross Site Request Forgery with Hmac Signatures
How Cross Site Request Forgery Manifests in Hmac Signatures
Cross Site Request Forgery (CSRF) in HMAC signature systems exploits the fundamental trust that servers place in properly signed requests. When HMAC signatures are used without proper anti-CSRF measures, attackers can trick authenticated users into making state-changing requests that appear legitimate to the server.
// Vulnerable HMAC implementation without CSRF protection
const hmac = crypto.createHmac('sha256', secretKey);
hmac.update(request.method + '
' + request.path + '
' + request.body);
const signature = hmac.digest('hex');
// Attacker crafts malicious request
// User visits evil.com while authenticated
// Browser automatically includes cookies
// Request appears valid due to correct HMAC
The core vulnerability occurs because HMAC signatures authenticate the request content but don't verify the request's origin. An attacker can create a malicious page that automatically submits a form or makes an API call. Since the victim's browser includes their authentication cookies and the HMAC signature validates correctly, the server processes the request as if it came from the legitimate user.
State-changing operations are particularly vulnerable: fund transfers, account modifications, or data deletions. The server sees a properly signed request with valid authentication and executes it without questioning whether the user actually intended to perform that action.
Real-world examples include banking applications where an attacker crafts a page that initiates a funds transfer to their account. The victim's browser sends the request with their session cookies, the HMAC validates correctly, and the transfer executes—all without the user's knowledge or consent.
HMAC Signatures-Specific Detection
Detecting CSRF vulnerabilities in HMAC systems requires examining both the signature generation and request handling logic. The key indicators are missing anti-CSRF tokens and improper origin verification.
// Detection pattern: missing CSRF token in HMAC workflow
const hmac = crypto.createHmac('sha256', secretKey);
hmac.update(request.method + '
' + request.path + '
' + request.body);
// Missing: hmac.update(csrfToken);
const signature = hmac.digest('hex');
middleBrick's black-box scanning specifically targets this vulnerability by examining the request flow. The scanner identifies HMAC endpoints and tests for CSRF susceptibility by attempting to replay signed requests across different origins and sessions. It checks whether the HMAC validation alone is sufficient for request processing.
Key detection patterns include:
- HMAC endpoints that accept requests without additional origin verification
- State-changing operations protected only by HMAC signatures
- Missing anti-CSRF tokens in the signature generation process
- Endpoints that process signed requests without checking the Referer header or Origin header
middleBrick's 12 security checks include specific CSRF detection for HMAC endpoints, testing whether an attacker could successfully replay a signed request from a different origin. The scanner also examines OpenAPI specifications to identify endpoints that should require additional CSRF protection but don't implement it.
HMAC Signatures-Specific Remediation
Effective CSRF protection for HMAC systems requires integrating anti-CSRF tokens into the signature generation process. The token must be unpredictable, tied to the user's session, and included in both the HMAC calculation and the request.
// Secure HMAC implementation with CSRF protection
function generateCsrfToken() {
return crypto.randomBytes(32).toString('hex');
}
function createSignedRequest(method, path, body, csrfToken, secretKey) {
const hmac = crypto.createHmac('sha256', secretKey);
hmac.update(method + '
' + path + '
' + body + '
' + csrfToken);
return {
method,
path,
body,
csrfToken,
signature: hmac.digest('hex')
};
}
// Server-side verification
app.post('/api/transfer', (req, res) => {
const expectedSignature = crypto
.createHmac('sha256', process.env.SECRET_KEY)
.update(
req.method + '\n' +
req.path + '\n' +
req.body + '\n' +
req.headers['x-csrf-token']
)
.digest('hex');
if (req.headers['x-signature'] !== expectedSignature) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Additional CSRF validation
if (!validateCsrfToken(req.headers['x-csrf-token'])) {
return res.status(403).json({ error: 'CSRF token invalid or missing' });
}
// Process the request
res.json({ success: true });
});
The remediation strategy involves three critical components: generating unpredictable CSRF tokens per session, including the token in the HMAC calculation, and verifying both the signature and the token on the server side. This ensures that even if an attacker obtains a valid signature, they cannot reuse it without the corresponding CSRF token.
For web applications, implement double-submit cookie pattern or synchronizer token pattern. The CSRF token should never be transmitted in URLs or predictable locations. Store it in an HttpOnly cookie and require it in a custom header or request body.
middleBrick's GitHub Action can automatically scan your staging APIs for CSRF vulnerabilities before deployment, ensuring your HMAC implementation includes proper anti-CSRF measures. The CLI tool allows you to test specific endpoints with --csrf flag to verify protection mechanisms are working correctly.