CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
Overview
Information exposure (also called information disclosure or information leakage) occurs when an application reveals sensitive data to users who should not have access to it. This vulnerability manifests across the application stack - from verbose error messages to improperly configured APIs to exposed backup files - and information that seems harmless individually can enable sophisticated attacks when combined (user enumeration + timing attacks + stack traces = account compromise).
OWASP Classification
A01:2025 - Broken Access Control
Risk
Information exposure creates multiple attack vectors:
- Reconnaissance: Attackers learn system architecture, technologies, file paths, database structure
- Credential theft: Exposed passwords, API keys, tokens in logs or responses
- User enumeration: Determine valid usernames, emails, account numbers
- Path disclosure: Reveal internal directory structure aiding path traversal attacks
- Business logic discovery: Understand workflows, pricing algorithms, access controls
- Version detection: Identify specific software versions to target known vulnerabilities
- Session prediction: Sequential session IDs enable session hijacking
- Data breach: Direct exposure of PII, financial data, health records
- Compliance violations: Fails GDPR, HIPAA, PCI-DSS data protection requirements
Information disclosure is often the first step in multi-stage attacks.
Common Sources of Information Exposure
Information leakage occurs through multiple channels:
- Error messages: Stack traces, SQL errors, path disclosures, debug information revealing internal architecture
- Application responses: Verbose status messages, timing differences, response size variations enabling enumeration
- Source code: Comments with credentials, debug code, exposed .git directories
- Configuration files: Exposed .env, config.php, application.properties with secrets
- Directory listings: Unprotected file browsing, backup files (.bak, ~, .old)
- API responses: Over-exposure of object properties, internal IDs, metadata beyond authorization
- HTTP headers: Server versions, technology stack details aiding targeted attacks
- Session tokens: Predictable or sequential session IDs enabling session hijacking
Remediation Steps
Core principle: Never return sensitive or internal information to a client unless it is explicitly required for that client's authorized function; all responses must be constructed from an allowlisted exposure model, not from internal state.
Locate the information exposure in your application
- Review the flaw details to identify the specific file, line number, and code pattern
- Identify what sensitive information is being exposed (stack traces, credentials, paths, user data, internal IDs)
- Trace the data flow: where is the information coming from and how is it being exposed (error messages, API responses, logs, headers)
- Determine the audience: who can see this information (authenticated users, anonymous users, public internet)
Use generic error messages for user-facing errors (Primary Defense)
- Never expose technical details: Replace detailed errors with generic messages
- BAD examples: "SQL Error: Column 'credit_card' doesn't exist", "Connection failed: Access denied for user 'admin'@'192.168.1.100'", "File not found: /var/www/app/config/database.yml"
- GOOD examples: "An error occurred processing your request", "Invalid credentials", "The requested resource could not be found"
- Implementation: Catch all exceptions at application boundary, log full details server-side, return generic message to user, use error codes/IDs (not technical details)
- Disable stack traces in production: Configure framework to hide stack traces from users
Implement proper access controls and minimize data exposure
- Authorize access: Authenticate user (who are you?), authorize access (do you have permission?), check object ownership (do you own this resource?)
- Same error for unauthorized and not found: Return identical "Not found" message whether resource doesn't exist or user lacks permission (prevents user enumeration)
- Filter API responses: Use DTOs/View Models to define exact response shape, never serialize entire database objects, remove sensitive fields (passwords, tokens, internal IDs)
- Field-level access controls: Only return fields user has permission to see
Secure configuration and deployment practices
- Disable debug mode: Turn off verbose logging and debug mode in production
- Remove development artifacts: Delete .git, .svn, .env from web root, remove backup files (.bak, ~, .swp, .old)
- Disable directory listing: Configure web server with Options -Indexes
- Set security headers: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, remove or generic Server header
- Configure custom error pages: Implement custom 404/500 error pages with generic messages
- Sanitize logs: Never log passwords, tokens, PII, credit cards
Monitor and audit information disclosure
- Regularly review error logs for information leakage (search for "stack trace", "exception", "SQL error")
- Implement rate limiting to prevent timing attacks
- Monitor for user enumeration attempts (failed login patterns, account existence checks)
- Review API responses for over-exposure of data (use API security scanning tools)
- Track access to sensitive resources and alert on suspicious patterns
Test the information disclosure fix thoroughly
- Verify the specific information is no longer exposed in error messages
- Test with invalid inputs to confirm generic error messages are shown
- Review all API endpoints to ensure minimal data exposure
- Check error pages (404, 500) display generic messages
- Verify .git, .env, backup files are not accessible
1. Error Message Testing
Trigger various errors:
- Invalid login: Wrong password
- Invalid input: Malformed data
- Database errors: Trigger SQL syntax error
- File errors: Access non-existent file
- Authorization errors: Access unauthorized resource
Expected: Generic error messages only, no stack traces or technical details
Information Disclosure Scanning
# Check for exposed sensitive files
curl https://yourapp.com/.git/config
curl https://yourapp.com/.env
curl https://yourapp.com/config/database.yml
curl https://yourapp.com/phpinfo.php
# Check directory listing
curl https://yourapp.com/uploads/
curl https://yourapp.com/backup/
# Expected: All return 404 or 403, not file contents or directory listings
User Enumeration Testing
Test timing and response differences:
- Login with valid user, wrong password
- Login with invalid user, any password
- Password reset for existing email
- Password reset for non-existent email
Expected: Identical timing and messages (no way to distinguish valid/invalid users)
API Over-Exposure Testing
Test API responses:
- Request user profile
- Request other users' profiles
- Check for sensitive fields in response
- Test with different permission levels
Expected: Only authorized data returned, sensitive fields filtered
Header and Fingerprinting
# Check HTTP headers
curl -I https://yourapp.com
Expected headers:
- X-Content-Type-Options: nosniff
- X-Frame-Options: DENY
- Generic or absent Server header (not "Apache/2.4.41 (Ubuntu) PHP/7.4.3")
Unexpected: Detailed version information
Dynamic Scan Guidance
For guidance on remediating this CWE when detected by dynamic (DAST) scanners:
- Dynamic Scan Guidance - Analyzing DAST findings and mapping to source code