CWE-200 in APIs
What is CWE-200?
CWE-200 is the Common Weakness Enumeration identifier for "Information Exposure." This weakness occurs when an application exposes sensitive information to users who shouldn't have access to it. The exposure can happen through error messages, logs, debugging output, or direct data leaks. What makes this particularly dangerous is that attackers can use this exposed information to plan more sophisticated attacks or gain unauthorized access to systems.
CWE-200 in API Contexts
In API environments, CWE-200 manifests in several specific ways that developers need to watch for. One common scenario is stack traces appearing in error responses. When an API endpoint fails, it might return a detailed error message containing file paths, database queries, or internal system information. For example:
{
"error": "SQL Error: SELECT * FROM users WHERE id = '1234'",
"stack_trace": "...
"/var/www/app/controllers/UserController.php:45"
}
Another API-specific manifestation is exposing internal IDs or database keys through URLs or response bodies. When an API returns user IDs like /api/users/12345, attackers can enumerate these IDs to discover valid records. Similarly, exposing internal database IDs in responses allows attackers to map your data structure.
API documentation and OpenAPI specifications can also inadvertently expose implementation details. If your Swagger spec includes internal endpoint names, database table references, or system architecture details, you're providing attackers with a roadmap of your infrastructure.
Detection
Detecting CWE-200 in APIs requires both manual review and automated scanning. Start by examining your API responses for sensitive information. Look for:
- Error messages containing stack traces or system paths
- Internal IDs, database keys, or implementation details in responses
- Debug information or verbose logging in production
- Headers that reveal server versions or frameworks
Automated scanning tools can identify many CWE-200 issues. middleBrick scans APIs for information exposure as part of its 12 security checks. The scanner tests unauthenticated endpoints and examines responses for sensitive data leakage. It specifically looks for stack traces, internal system information, and data exposure patterns that indicate CWE-200 vulnerabilities.
When using middleBrick, you'll receive a security score with specific findings related to information exposure. The tool checks for verbose error messages, debug endpoints, and data leakage in API responses. For example, if your API returns detailed error messages with stack traces, middleBrick will flag this as a high-severity finding and provide remediation guidance.
Manual testing should include attempting to access error conditions deliberately. Trigger 404s, 500 errors, and authentication failures to see what information your API reveals. Check both authenticated and unauthenticated endpoints, as information exposure can occur in either context.
Remediation
Fixing CWE-200 issues in APIs requires a multi-layered approach. First, implement proper error handling that never exposes internal details to clients. Here's an example of bad vs good error handling in Node.js:
// BAD - Exposes internal details
app.get('/api/users/:id', (req, res) => {
User.findById(req.params.id)
.then(user => {
if (!user) {
res.status(404).json({
error: 'User not found',
message: `No user with ID ${req.params.id} exists`,
stack: new Error().stack
});
}
})
.catch(err => {
res.status(500).json({
error: 'Database error',
details: err.message,
stack: err.stack
});
});
});
// GOOD - Generic error responses
app.get('/api/users/:id', (req, res) => {
User.findById(req.params.id)
.then(user => {
if (!user) {
return res.status(404).json({ error: 'Resource not found' });
}
res.json(user);
})
.catch(() => {
res.status(500).json({ error: 'Internal server error' });
});
});
For logging, ensure sensitive information never gets logged in production. Use structured logging with proper redaction:
const log = require('pino')({
level: process.env.LOG_LEVEL || 'info'
});
function safeLogRequest(req) {
const sanitized = {
method: req.method,
url: req.path,
headers: {
'user-agent': req.get('user-agent'),
'x-forwarded-for': req.ip
}
// Remove authorization headers, cookies, etc.
};
log.info(sanitized);
}
Implement rate limiting and request validation to prevent information gathering through enumeration attacks. Use UUIDs or hashed IDs instead of sequential integers:
// BAD - Sequential IDs
app.get('/api/users/12345')
// GOOD - UUIDs or hashed IDs
app.get('/api/users/550e8400-e29b-41d4-a716-446655440000')
Finally, review your OpenAPI specifications. Remove internal implementation details, use generic endpoint names, and avoid exposing your data model structure. Consider having a security review of your API documentation before publishing it.