Pii Leakage in Adonisjs with Jwt Tokens
Pii Leakage in Adonisjs with Jwt Tokens — how this specific combination creates or exposes the vulnerability
AdonisJS is a Node.js web framework that commonly uses JSON Web Tokens (JWT) for stateless authentication. When JWTs are used without care, personally identifiable information (PII) can be inadvertently exposed through token content, logs, or error messages, and through mismatched validation and serialization practices.
JWTs are often stored in the payload with user identifiers and profile fields. If a token includes fields such as email, name, or other direct PII, any service that can read or intercept the token can extract that data. Even if the token is cryptographically signed, exposure of the token (e.g., via logs, browser storage, or insecure transmission) leads to PII leakage because the payload is typically base64-encoded and not encrypted.
In AdonisJS, developers sometimes attach sensitive user properties directly to the token payload during creation. For example, including a full user object or email in the JWT payload means that any component with token access can decode and view that information. Tokens may also be logged inadvertently in application logs, especially if debug or error reporting prints the authorization header or token contents. Another risk occurs when token validation does not strictly enforce scopes or claims, allowing broader access than intended and increasing the surface for PII exposure through token replay or misuse.
Additionally, if the application serializes user data into the token without filtering PII, and that token is transmitted over non-HTTPS channels, interception becomes a realistic threat. Even with HTTPS, storing tokens in insecure client-side storage (e.g., local storage) can lead to token theft and subsequent PII exposure. AdonisJS applications must ensure that tokens carry only necessary identifiers, avoid embedding sensitive fields, and enforce strict transport and storage practices to mitigate this risk.
Jwt Tokens-Specific Remediation in Adonisjs — concrete code fixes
To reduce PII leakage risk with JWTs in AdonisJS, limit token contents to minimal identifiers, avoid storing sensitive data, and enforce secure transmission and storage practices. Below are concrete code examples showing how to create and verify tokens safely.
When generating a token, include only a user ID and necessary metadata, and exclude email or other PII. Use environment-based secret management and short expiration times to reduce exposure windows.
import { base64url } from 'jose';
import { DateTime } from 'luxon';
import { JwtProvider } from '@ioc/Adonis/Addons/Jwt';
export default class AuthController {
public async login({ request, auth, response }) {
const user = await auth.authenticate();
const token = await JwtProvider.use('jwt').issue({
sub: String(user.id), // minimal identifier, not PII
iat: Math.floor(DateTime.local().toSeconds()),
exp: Math.floor(DateTime.local().plus({ hours: 1 }).toSeconds()),
scopes: ['read', 'write'], // least-privilege scope
});
// Send only the token via secure, httpOnly cookie or Authorization header
response.cookie('token', token.toString(), {
httpOnly: true,
secure: true,
sameSite: 'strict',
});
return response.json({ ok: true });
}
}
When verifying tokens, ensure that the payload is not used to expose PII and that claims are validated strictly. Do not trust decoded payload for authorization decisions without re-checking server-side permissions.
import { HttpContextContract } from '@ioc/Adonis/Core/HttpContext';
import { JwtProvider } from '@ioc/Adonis/Addons/Jwt';
export default class UserController {
public async me({ request, response }) {
const token = request.headers().authorization?.replace('Bearer ', '');
if (!token) {
return response.unauthorized();
}
try {
const payload = await JwtProvider.use('jwt').verify(token);
// Use only the subject ID to fetch user; do not rely on payload PII
const user = await User.findOrFail(payload.sub);
return response.json({ id: user.id, username: user.username });
} catch (error) {
return response.unauthorized();
}
}
}
Additional remediation steps include:
- Use short-lived tokens and refresh token rotation to limit the usefulness of leaked tokens.
- Transmit tokens only over HTTPS and enforce HSTS to prevent downgrade attacks.
- Store tokens in httpOnly, Secure, SameSite=Strict cookies when possible, avoiding local storage.
- Audit logs to ensure tokens or authorization headers are not printed in application or error logs.
- Apply strict CORS and CSRF protections to reduce cross-origin leakage risks.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |