Xml External Entities in Adonisjs with Jwt Tokens
Xml External Entities in Adonisjs with Jwt Tokens — how this specific combination creates or exposes the vulnerability
XML External Entity (XXE) injection occurs when an application processes XML input that references external entities, and the XML parser is configured to resolve them. In AdonisJS, this risk can intersect with JWT token handling when developers accept XML payloads (for example in advanced SAML or legacy SOAP integrations) and then embed information extracted from those payloads into JWT tokens, or accept JWTs that are XML-formatted (non-standard, but possible in niche federation scenarios).
In a typical AdonisJS application using JWT tokens, a developer might parse an incoming XML document to extract user attributes (such as roles or permissions), then include those attributes as claims when signing a JWT. If the XML parser resolves external entities, an attacker can supply an XML payload that references local files (e.g., file:///etc/passwd) or internal network resources via http:// or https:// URLs. Successful resolution can lead to sensitive data exposure, SSRF, or denial of service. Because the JWT is later used for authentication and authorization, the tainted claims may be trusted by downstream services, amplifying the impact.
The vulnerability is not inherent to JWT itself—JWTs are just a token format—but to the XML processing stage that precedes token creation or validation. AdonisJS does not include an XML parser in its core framework; however, if you introduce an XML library (such as xmldom or similar) and configure it to resolve external references, you create the condition for XXE. The risk is higher when the XML is used to enrich JWT claims, because the token may be accepted system-wide based on those claims.
Consider an endpoint that accepts an XML profile, reads a user role from it, and then issues a JWT containing that role. An attacker could submit an XML document with a malicious external entity that points to an internal metadata service. If the parser resolves the entity, the application may unintentionally disclose sensitive configuration data, and embed it into the JWT. Later, authorization checks that rely on the JWT role may be bypassed or misapplied.
Because middleBrick scans test the unauthenticated attack surface, it can surface indicators that an API accepts XML inputs and issues JWTs, highlighting the need to review XML parsing configurations. The scan does not modify your application; it reports findings with remediation guidance so you can adjust parsing behavior and claim construction to avoid introducing unsafe data into JWT tokens.
Jwt Tokens-Specific Remediation in Adonisjs — concrete code fixes
Remediation focuses on two areas: secure XML handling (or avoiding XML entirely) and ensuring JWT claims are derived from safe, validated sources. Below are concrete steps and code examples tailored for AdonisJS.
1. Avoid XML or disable external entity resolution
If you do not need XML, remove any XML parser dependencies. If you must parse XML, configure the parser to disallow external entities and DOCTYPE declarations. For example, using xmldom, avoid the default behavior and explicitly disable external resolution:
const { DOMParser } = require('@xmldom/xmldom');
const parser = new DOMParser({
externalEntityReference: () => {
// Reject any external entity reference
return null;
},
errorHandler: {
warning: (w) => { throw new Error(w); },
error: (e) => { throw new Error(e); },
fatalError: (e) => { throw new Error(e); }
}
});
const xmlString = '<?xml version="1.0"?><user><role>admin</role></user>'; // example input
const document = parser.parseFromString(xmlString);
const roleNode = document.getElementsByTagName('role')[0];
const role = roleNode ? roleNode.textContent : null;
if (!role) {
throw new Error('Invalid role in XML');
}
This ensures that entities such as &file; or &internal; are not resolved.
2. Validate and sanitize claims before signing JWTs
When constructing JWT tokens in AdonisJS, validate and sanitize all data that will become a claim. Do not directly embed data extracted from XML without strict checks:
const jwt = use('Adonis/Addons/Jwt');
function buildToken(user, roleFromXml) {
// Whitelist acceptable roles; do not trust XML values blindly
const validRoles = ['user', 'admin', 'editor'];
const role = validRoles.includes(roleFromXml) ? roleFromXml : 'user';
const payload = {
sub: user.id,
email: user.email,
role: role,
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + (60 * 60) // 1 hour
};
return jwt.sign(payload, process.env.JWT_SECRET || 'change-me', { algorithm: 'HS256' });
}
// Example usage after safe parsing
const token = buildToken(currentUser, role);
By constraining roles to a known set, you prevent attackers from injecting privileged claims via XML external entities.
3. Secure JWT verification and claim usage
When verifying JWTs in AdonisJS, ensure you validate the signature, issuer, audience, and expiration. Do not trust claims that originated from unvalidated XML:
try {
const payload = await jwt.verify(token, process.env.JWT_SECRET || 'change-me', { algorithms: ['HS256'] });
// Use payload.sub, payload.role, etc., with confidence that they were signed by your service
const user = await User.find(payload.sub);
if (!user || user.role !== payload.role) {
throw new Error('Insufficient permissions');
}
// proceed with authorized action
} catch (error) {
throw new Error('Invalid token');
}
4. Use middleware to enforce safe authentication flows
In AdonisJS, create an authentication middleware that validates tokens and enforces role-based access without re-parsing XML on each request:
class AuthMiddleware {
async handle({ request, auth }, next) {
const token = request.header('authorization')?.replace('Bearer ', '');
if (!token) {
throw new Error('Unauthorized');
}
const payload = await auth.jwt.verify(token);
request.authUser = payload;
await next();
}
}
module.exports = AuthMiddleware;
This approach keeps JWT handling separate from XML parsing and ensures that authorization relies on verified tokens rather than raw XML-derived data.
5. Monitoring and scanning
Use tools like middleBrick to scan your API endpoints. The scanner checks for indicators such as XML parsing behavior and JWT issuance patterns, and it reports findings with remediation guidance. The CLI can be run locally with middlebrick scan <url>, and the GitHub Action can be added to CI/CD pipelines to fail builds if risk scores drop below your chosen threshold.