Injection Flaws with Jwt Tokens
How Injection Flaws Manifests in Jwt Tokens
Injection flaws in JWT tokens occur when untrusted data is embedded into token payloads without proper validation or sanitization. These vulnerabilities can lead to authentication bypass, privilege escalation, and data exfiltration.
The most common JWT injection pattern involves manipulating the sub (subject) claim or custom claims to inject malicious payloads. For example, an attacker might modify a JWT token to include SQL injection payloads in user ID fields:
// Vulnerable: Direct use of JWT sub claim in database query
const userId = jwt.decode(token).sub;
const user = await db.query(`SELECT * FROM users WHERE id = ${userId}`);This allows an attacker to craft a token with sub set to 1 OR 1=1, potentially returning all users or bypassing authorization checks.
Another critical injection vector is NoSQL injection through MongoDB queries. When JWT claims are used directly in NoSQL queries without proper validation:
// Vulnerable: NoSQL injection via JWT claims
const role = jwt.decode(token).role;
const user = await db.collection('users').findOne({ role: role });An attacker could set role to { $ne: null } to bypass role-based access controls.
Time-based SQL injection is particularly dangerous when JWT claims are used in time comparisons:
// Vulnerable: Time-based SQL injection
const issuedAt = jwt.decode(token).iat;
const query = `SELECT * FROM sessions WHERE user_id = ${userId} AND issued_at > ${issuedAt}`;Attackers can manipulate iat values to extract data through timing analysis or cause authentication bypass.
Command injection through JWT claims is another serious threat when tokens are used to construct shell commands:
# Vulnerable: Command injection via JWT claim
userId=$(echo $JWT_SUBJECT | cut -d'@' -f1)
result=$(grep $userId /etc/passwd)An attacker could craft a JWT with sub set to admin; rm -rf /, potentially executing arbitrary commands.
Template injection occurs when JWT claims are used in template rendering without proper escaping:
// Vulnerable: Template injection
const template = `Welcome, {{user.name}}!`;
const rendered = template.replace('{{user.name}}', jwt.decode(token).name);An attacker could inject template syntax to manipulate the rendered output or cause template engine errors.
Jwt Tokens-Specific Detection
Detecting injection flaws in JWT tokens requires both static analysis and dynamic testing. middleBrick's scanning engine specifically targets JWT injection vulnerabilities through multiple detection methods.
middleBrick performs runtime analysis by submitting crafted JWT tokens to your endpoints and monitoring responses for injection indicators. The scanner tests for SQL injection patterns by modifying the sub claim with common injection payloads:
// middleBrick test payloads for SQL injection
{
"sub": "1 OR 1=1",
"sub": "1' OR '1'='1",
"sub": "1; DROP TABLE users; --"
}The scanner analyzes response patterns, HTTP status codes, and timing differences to identify successful injections.
For NoSQL injection detection, middleBrick tests MongoDB-specific operators by injecting payloads into custom claims:
// middleBrick NoSQL injection test cases
{
"role": "{ $ne: null }",
"permissions": "{ $exists: true }",
"admin": "{ $gt: 0 }"
}The scanner checks if these operators affect query results, indicating potential NoSQL injection vulnerabilities.
middleBrick also performs template injection testing by injecting template syntax into JWT claims:
// Template injection test payloads
{
"name": "{{ malicious_payload }}"
}The scanner analyzes rendered responses for template processing artifacts or error messages.
Time-based injection detection involves submitting JWT tokens with manipulated timestamps and measuring response variations:
// Time-based injection test cases
{
"iat": "0 OR 1=1",
"exp": "9999999999 OR 1=1"
}middleBrick's analysis includes checking for database error messages, stack traces, or unexpected behavior in responses.
The scanner also validates proper JWT claim validation by testing if tokens with invalid or missing claims are properly rejected:
// Invalid claim test cases
{
"sub": null,
"sub": "invalid-user-id",
"iat": "not-a-timestamp"
}middleBrick provides severity ratings based on the injection type, potential impact, and exploitability of discovered vulnerabilities.
Jwt Tokens-Specific Remediation
Remediating JWT injection flaws requires implementing proper input validation, parameterized queries, and secure JWT handling practices. Here are specific code fixes for common JWT injection vulnerabilities.
For SQL injection prevention, always use parameterized queries instead of string concatenation:
// Secure: Parameterized queries
const userId = jwt.decode(token).sub;
const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);This ensures user input is treated as data, not executable SQL code.
For NoSQL injection protection, validate and sanitize JWT claims before using them in queries:
// Secure: Input validation and sanitization
const role = jwt.decode(token).role;
if (typeof role !== 'string' || !allowedRoles.includes(role)) {
throw new Error('Invalid role claim');
}
const user = await db.collection('users').findOne({ role: role });Implement a whitelist approach for JWT claims to prevent injection of special operators.
For command injection prevention, never use JWT claims directly in shell commands:
// Secure: Safe command execution
const userId = jwt.decode(token).sub;
if (!/^[a-zA-Z0-9@.]+$/.test(userId)) {
throw new Error('Invalid user ID format');
}
const { execSync } = require('child_process');
const result = execSync(`grep ${userId} /etc/passwd`, { shell: '/bin/bash' });Validate input against strict patterns and use safe execution methods.
For template injection protection, use proper template engines with auto-escaping:
// Secure: Template engine with escaping
const template = require('mustache');
const data = { name: jwt.decode(token).name };
const rendered = template.render('Welcome, {{name}}!', data);Never use string replacement for template rendering with untrusted data.
Implement JWT claim validation middleware to prevent injection through malformed tokens:
// Secure: JWT claim validation middleware
function validateJwtClaims(token) {
const decoded = jwt.decode(token, { complete: true });
const claims = decoded.payload;
// Validate required claims
if (!claims.sub || typeof claims.sub !== 'string') {
throw new Error('Missing or invalid sub claim');
}
// Validate claim formats
if (!Number.isInteger(claims.iat) || claims.iat < 0) {
throw new Error('Invalid iat claim');
}
return claims;
}Always validate JWT claims before using them in any security-sensitive operations.
For time-based injection prevention, use proper timestamp validation:
// Secure: Timestamp validation
function validateTimestamp(timestamp) {
if (typeof timestamp !== 'number' || timestamp < 0 || timestamp > Date.now() / 1000 + 3600) {
throw new Error('Invalid timestamp');
}
return true;
}Implement comprehensive logging for JWT processing to detect injection attempts:
// Secure: JWT processing logging
function processJwt(token) {
try {
const claims = validateJwtClaims(token);
// Process claims securely
} catch (error) {
console.warn(`JWT processing error: ${error.message}`, { token });
throw error;
}
}These remediation techniques eliminate injection vulnerabilities while maintaining JWT functionality.