Pii Leakage in Express with Api Keys
Pii Leakage in Express with Api Keys — how this specific combination creates or exposes the vulnerability
API keys are commonly used in Express services for client authentication and authorization. When keys are handled or logged without care, they can become a vector for PII leakage. A key itself may be considered sensitive metadata, and its exposure can enable attackers to map, fingerprint, or even abuse downstream services. In Express, keys often arrive in headers, query parameters, or cookies; if responses include debug data, stack traces, or verbose logging that contains the key, or if the server echoes request values back in error messages, PII related to the key usage can be disclosed.
Consider an Express route that authenticates via an API key and returns a detailed error on failure. If the error response includes the key value or surrounding request metadata, an attacker can harvest keys and correlate them with other data to identify user accounts or usage patterns. Logging middleware that writes the full request URL, headers, or body to a log sink can similarly expose keys and associated PII when logs are aggregated or accessed by unauthorized parties. Transport risks also matter: if TLS is not enforced consistently, keys can be intercepted, and with them session context or identifying information.
Another scenario involves integrations where the API key is used to call external services that return PII. If the Express app caches or mirrors these responses without proper sanitization, key-related data may be stored or surfaced in a way that leaks PII. For example, a developer might inadvertently include the key in URLs stored in a database alongside user identifiers, creating a linkage that exposes both authentication material and personal data. SSRF-related issues can also amplify risk: an attacker forcing the server to make requests with embedded keys can trigger disclosures from internal or partner endpoints that return sensitive information.
OpenAPI/Swagger analysis helps surface these risks by aligning the spec’s security schemes with runtime behavior. By resolving $ref definitions and cross-referencing declared security requirements with actual endpoints, scanners can detect inconsistencies such as keys accepted in query parameters (high exposure risk) and missing security on high-sensitivity operations. This is especially important when LLM-related endpoints are involved; unprotected completions endpoints that accept API keys can leak prompts or configuration details that constitute PII under certain contexts.
Api Keys-Specific Remediation in Express — concrete code fixes
Remediation focuses on reducing exposure of API keys in logs, error messages, and URLs while enforcing secure transport and least privilege. Avoid echoing keys in responses; sanitize error output and disable verbose stack traces in production. Use environment variables for keys, never hardcode them, and rotate them regularly. Apply structured logging that excludes sensitive fields, and ensure TLS is mandatory.
Example 1: Secure key validation without echoing the key
const express = require('express');
const app = express();
const VALID_KEYS = new Set([
process.env.API_KEY_PROD,
process.env.API_KEY_STAGING
].filter(Boolean));
app.use((req, res, next) => {
const key = req.get('x-api-key') || req.query.api_key;
if (!key || !VALID_KEYS.has(key)) {
return res.status(401).json({ error: 'Invalid API key' });
}
// Attach a normalized principal, not the raw key
req.principal = { scope: 'api_key' };
next();
});
app.get('/data', (req, res) => {
// Do not log the key; log only metadata
console.info('Authenticated request', { method: req.method, path: req.path, principal: req.principal });
res.json({ message: 'ok' });
});
app.use((err, req, res, next) => {
// Avoid exposing keys in error responses
console.error('Error handled', { path: req.path, error: err.message });
res.status(500).json({ error: 'Internal error' });
});
app.listen(3000, () => console.log('Server running on port 3000'));
Example 2: Middleware to strip keys from logs and prevent query-param usage
const express = require('express');
const app = express();
// Reject API keys in query parameters to reduce leakage surface
app.use((req, res, next) => {
if (req.query && req.query.api_key) {
return res.status(400).json({ error: 'API key must be sent in headers' });
}
next();
});
// Centralized logging that redacts sensitive headers
app.use((req, res, next) => {
const logObject = {
timestamp: new Date().toISOString(),
method: req.method,
url: req.originalUrl,
ip: req.ip
// Intentionally omitting headers that may contain keys
};
console.log(JSON.stringify(logObject));
next();
});
// Example route using header-based key validation
app.post('/action', (req, res) => {
const key = req.get('x-api-key');
if (!key || key !== process.env.API_KEY_ACTION) {
return res.status(403).json({ error: 'Forbidden' });
}
res.json({ status: 'processed' });
});
app.use((err, req, res, next) => {
// Generic error to avoid key leakage via stack traces
res.status(500).json({ error: 'An error occurred' });
});
app.listen(3000, () => console.log('Server ready'));
Operational practices
- Use HTTP Strict Transport Security (HSTS) and reject insecure requests.
- Rotate keys via automation and revoke compromised keys immediately.
- Scope keys to least privilege and avoid embedding user PII in key identifiers.
- Integrate scans from the CLI (
middlebrick scan <url>) or the GitHub Action to enforce security gates before deployment; the Pro plan adds continuous monitoring and alerts to catch regressions.
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 |