Pii Leakage in Express with Bearer Tokens
Pii Leakage in Express with Bearer Tokens — how this specific combination creates or exposes the vulnerability
PII leakage in an Express API that uses Bearer tokens typically occurs when authenticated responses or logs inadvertently expose sensitive data such as email addresses, names, or other identifying information. Even when token-based access control is in place, improper handling of data after authentication can lead to exposure of PII. For example, an endpoint that returns a full user record including fields like email, name, or ssn without applying field-level filtering can disclose PII to any client that presents a valid token.
Bearer tokens themselves do not cause PII leakage, but they can enable broader access if authorization is not tightly scoped. If an authorization check confirms token validity but does not enforce field-level or row-level permissions, an attacker who obtains a token (through theft, insecure storage, or insufficient token binding) can access more data than intended. Additionally, Express middleware that logs request or response bodies without redaction can persist PII in logs, especially when tokens are included in headers and responses contain sensitive user details.
Another common scenario involves improper error handling. Express error handlers that return stack traces or detailed internal data might include PII such as database identifiers or user emails when a request is authenticated with a Bearer token. Without explicit suppression of sensitive fields in error responses, even failed authorization attempts or validation errors can leak information to authenticated clients.
Middleware that parses and forwards authentication headers without validating token scope or audience can also contribute to PII exposure. For instance, an Express route that trusts a token’s payload to decide what data to return might inadvertently expose PII if the token contains overly permissive claims or if the route does not apply consistent filtering across all data access paths.
To detect PII leakage, scanning tools examine whether authenticated responses include sensitive fields, whether logs retain PII, and whether error messages expose data when a Bearer token is present. These checks focus on the intersection of authentication and data exposure controls to ensure that valid tokens do not lead to unintended information disclosure.
Bearer Tokens-Specific Remediation in Express — concrete code fixes
Remediation focuses on ensuring that authentication via Bearer tokens does not equate to unrestricted data exposure. Implement strict field filtering, avoid logging sensitive data, and sanitize error responses for authenticated requests.
1. Field-level filtering for authenticated responses
Create a helper that strips PII from user objects before sending responses. Apply this filter consistently for all routes that return user or profile data, regardless of token validity.
// server.js
function sanitizeUser(user) {
return {
id: user.id,
username: user.username,
// Explicitly exclude PII
};
}
app.get('/api/profile', (req, res) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
// Verify token and fetch user (pseudo)
const user = { id: 1, username: 'jdoe', email: '[email protected]', ssn: '123-45-6789' };
res.json(sanitizeUser(user));
});
2. Prevent logging of PII and tokens
Ensure logging middleware does not capture headers containing Authorization or response bodies with sensitive fields.
// logger.middleware.js
function safeLogger(req, res, next) {
const safeHeaders = { ...req.headers };
if (safeHeaders.authorization) {
safeHeaders.authorization = '[redacted]';
}
// Avoid logging res body in production
console.log('Request:', req.method, req.path, safeHeaders);
next();
}
app.use(safeLogger);
3. Secure error handling for authenticated requests
Customize error handlers to omit PII when responding to requests that include Bearer tokens.
// error-handler.middleware.js
app.use((err, req, res, next) => {
const hasAuth = req.headers.authorization;
if (hasAuth) {
// Do not expose stack or PII in errors for authenticated requests
res.status(err.status || 500).json({ error: 'Internal server error' });
} else {
res.status(err.status || 500).json({ error: err.message });
}
});
4. Validate token scope and claims before data access
Check token payloads for necessary scopes and avoid using claims to directly decide which PII fields to return.
// auth.middleware.js
function verifyScope(requiredScope) {
return (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Unauthorized' });
const payload = decodeToken(token); // implement JWT decode safely
if (!payload.scopes?.includes(requiredScope)) {
return res.status(403).json({ error: 'Insufficient scope' });
}
req.user = { id: payload.sub, scopes: payload.scopes };
next();
};
}
// Usage
app.get('/api/admin', verifyScope('admin:read'), (req, res) => {
// Load minimal data and apply additional filtering
res.json({ message: 'Admin access granted' });
});
5. Rate limiting and anomaly detection tied to token identity
Apply rate limits using token or user identifiers to reduce the impact of compromised tokens that could be used to harvest PII.
const rateLimit = require('express-rate-limit');
const authLimiter = rateLimit({
keyGenerator: (req) => {
const token = req.headers.authorization?.split(' ')[1];
return token || req.ip;
},
windowMs: 15 * 60 * 1000,
max: 100,
});
app.use('/api/', authLimiter);
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 |