Xpath Injection with Jwt Tokens
How Xpath Injection Manifests in Jwt Tokens
Xpath injection in Jwt tokens occurs when applications use JWT claims to construct XPath queries without proper sanitization. Attackers can manipulate token claims to alter query logic and extract unauthorized data from XML databases.
Common Jwt token claims vulnerable to XPath injection:
sub(subject) - often used as user identifier in XPath queriesrole- used for authorization checksemail- used to fetch user-specific data
Attack Pattern 1: BOLA via XPath
// Vulnerable code - attacker can manipulate sub claim to access other users' data
const jwt = require('jsonwebtoken');
const xpath = require('xpath');
const dom = require('xmldom').DOMParser;
function getUserData(token) {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
const doc = new dom().parseFromString(xmlData);
// Attacker controls decoded.sub and can inject XPath
const xpathQuery = `//users[user_id='${decoded.sub}']`;
const result = xpath.select(xpathQuery, doc);
return result[0];
}
Attack Pattern 2: Authentication Bypass
// Vulnerable admin check - attacker can inject XPath to bypass role validation
function isAdmin(token) {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
const doc = new dom().parseFromString(xmlData);
// Attacker can set role claim to: 'admin' or '1'='1'
const xpathQuery = `//users[user_id='${decoded.sub}' and role='${decoded.role}']`;
const result = xpath.select(xpathQuery, doc);
return result.length > 0;
}
Real-world impact: CVE-2021-39177 demonstrated how JWT claims used in XPath queries led to complete data exposure in enterprise applications.
Jwt Tokens-Specific Detection
Detecting XPath injection in JWT implementations requires examining how token claims interact with XML data access patterns.
Code Review Indicators:
- Direct interpolation of JWT claims into XPath queries
- XPath queries constructed using string concatenation with user-controlled data
- XML data sources accessed using JWT claims as identifiers
middleBrick Scanning Approach:
middleBrick's black-box scanner tests Jwt token endpoints by:
- Submitting JWTs with crafted claims containing XPath injection payloads
- Monitoring XML database responses for data leakage
- Analyzing error messages that reveal XML structure
Automated Testing with middleBrick CLI:
# Scan Jwt token endpoint for XPath injection vulnerabilities
middlebrick scan https://api.example.com/auth --token "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
Manual Testing Techniques:
# Test with XPath injection payloads in JWT claims
JWT="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.YOUR_SIGNATURE"
# Payload examples to test:
# 1. ' or '1'='1
# 2. ' and role='admin' and '1'='1
# 3. ' union select * from users where '1'='1
middleBrick's Property Authorization check specifically flags when JWT claims are used to construct database queries without proper validation.
Jwt Tokens-Specific Remediation
Fixing XPath injection in JWT implementations requires input validation and query parameterization.
Remediation Pattern 1: Input Validation
const jwt = require('jsonwebtoken');
const xpath = require('xpath');
const dom = require('xmldom').DOMParser;
function validateJwtClaim(claim, type) {
switch(type) {
case 'userId':
// Only allow alphanumeric user IDs
return /^[a-zA-Z0-9_-]+$/.test(claim);
case 'role':
// Validate against known roles
const validRoles = ['user', 'admin', 'moderator'];
return validRoles.includes(claim);
default:
return false;
}
}
function getUserData(token) {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
if (!validateJwtClaim(decoded.sub, 'userId')) {
throw new Error('Invalid user ID format');
}
const doc = new dom().parseFromString(xmlData);
const xpathQuery = `//users[user_id='${decoded.sub}']`;
const result = xpath.select(xpathQuery, doc);
return result[0];
}
Remediation Pattern 2: Parameterized XPath Queries
const xpath = require('xpath');
const dom = require('xmldom').DOMParser;
function getUserDataSafe(token) {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
// Use XPath variables instead of string interpolation
const doc = new dom().parseFromString(xmlData);
const select = xpath.useNamespaces({'x': 'http://example.com/ns'});
// Bind user_id as a parameter
const result = select(
'//users[user_id=$user_id]/data',
doc,
null,
{ user_id: decoded.sub }
);
return result[0];
}
Remediation Pattern 3: Whitelist-Based Access Control
const jwt = require('jsonwebtoken');
// Pre-computed lookup instead of XPath queries
const userDataMap = {
'user123': { name: 'John Doe', role: 'user' },
'admin456': { name: 'Jane Smith', role: 'admin' }
};
function getUserDataSecure(token) {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
// Direct lookup - no XPath involved
const userData = userDataMap[decoded.sub];
if (!userData) {
throw new Error('User not found');
}
return userData;
}
middleBrick Pro Plan Advantage: Continuous monitoring can automatically scan your Jwt token endpoints on a schedule, alerting you if new XPath injection vulnerabilities appear after code changes.