Sensitive Data in Error Messages and Debug Code
CWE-209, CWE-215, CWE-550, CWE-756
Information disclosure through error messages occurs when applications expose sensitive information in error pages, logs, debug output, or exception messages. This includes:
Error messages are meant to help developers debug, but in production they become a roadmap for attackers. Stack traces, database queries, file paths, and configuration details reveal the application's architecture and vulnerabilitis.
Real-World Attack Scenarios
Scenario 1: Database Error Revealing SQL Injection Points
A user searches products with a single quote:
GET /search?query=test'The vulnerable error response:
Error: You have an error in your SQL syntax; check the manual that corresponds
to your MySQL server version for the right syntax to use near
"'test''" at line 1
SQL Query: SELECT * FROM products WHERE name LIKE '%test'%' AND active = 1What the attacker learns:
Database is MySQL (version from error)
Exact SQL query structure:
SELECT * FROM products WHERE name LIKE '%[INPUT]%' AND active = 1SQL injection is possible (query error shows uncaught exception)
There's an
activefield (logic discovery)Table name and column names (
products,name,active)
The attack:
With this information, attacker crafts SQL injection:
Result:
Complete SQL injection exploitation
Database compromise
Data theft or destruction
The fix:
Never show SQL errors to users:
Finding it: Submit invalid input (single quotes, special characters). Check error messages for SQL syntax errors, table/column names, query structure.
Exploit:
Scenario 2: Stack Trace Revealing File Paths and Code
Application has an unhandled exception:
The verbose error response:
What the attacker learns:
Web root is
/var/www/html(server architecture)File structure:
/api/user.php- handles user API/src/User/Manager.php- user management logic/api/router.php- routing logic
Code flow: How requests are routed and processed
Function names:
handleRequest(),getUserProfile()(API endpoints)PHP version and framework (error format)
Exact line numbers where errors occur
The attack:
With this knowledge, attacker:
Enumerates file structure
Tests each API endpoint knowing exact code paths
Identifies vulnerable functions
Finds bypass opportunities in error handling
Result:
Complete application architecture exposed
Targeted exploitation possible
Privilege escalation paths identified
The fix:
Catch all exceptions and return generic errors:
Finding it: Trigger exceptions with invalid input. Check error messages for stack traces, file paths, function names.
Scenario 3: Debugging Code Left in Production
Application has debugging statements that reveal sensitive data:
What's leaked:
Emails - User enumeration (who has accounts)
Password hashes - Can be cracked offline
API keys - Direct service access
Database credentials - Database compromise
Full user objects - All user data exposed
The attack:
Attacker:
Captures API response with full user object
Gets user's API key
Uses API key to access other services
Accesses password hash, runs offline crack
Logs in with real password
Result:
Complete user account compromise
Access to all services
Database and API compromise
The fix:
Remove all debugging code in production:
Finding it: Check response bodies for unnecessary data. Search code for console.log(), println(), print_r(). Review debug variables in output.
Scenario 4: Version Information in Error Pages
Application exposes framework and library versions:
What the attacker learns:
Apache 2.4.41 - Version with known CVEs
PHP 7.4.3 - Version with known vulnerabilities
Laravel 8.12.0 - Framework version with known exploits
Application structure - Uses Models (Laravel MVC)
The attack:
Attacker:
Looks up CVE-2020-xxxx for Apache 2.4.41
Finds public exploit for PHP 7.4.3
Searches Exploit-DB for Laravel 8.12.0
Finds remote code execution vulnerability
Exploits application directly
Result:
Remote code execution
Server compromise
Application takeover
The fix:
Hide version information:
Finding it: Check HTTP headers. Look at error pages. Search for version strings in responses.
Exploit:
Scenario 5: No Custom Error Page (Information Leakage)
Application displays default server error pages:
What the attacker learns:
Exact server configuration
Installed modules
File paths
Known vulnerabilities for that configuration
The fix:
Create custom error pages:
Configure in web server:
Finding it: Trigger errors and check if default error pages shown instead of custom pages.
Scenario 6: Sensitive Information in Debug Comments
Developer leaves credentials or sensitive info in comments:
What the attacker learns:
Debug credentials:
admin / AdminDebug123!Database credentials: User and password
Database server:
db.internal.company.comDatabase name:
prod_dbPort:
5432
The attack:
Attacker:
Uses debug credentials to log in as admin
Or uses database credentials to connect directly to PostgreSQL
Dumps entire database
Complete compromise
Result:
Admin access
Database access
Complete data breach
The fix:
Never leave credentials in comments:
Finding it: Search source code for comments containing: password, key, secret, TODO, FIXME, DEBUG, HACK.
Exploit:
How to Identify Information Disclosure During Testing
1. Trigger errors intentionally
2. Check error messages for:
SQL syntax and queries
File paths and directory structure
Stack traces with function names
Variable names and values
Library/framework versions
Database information
API endpoints
Server configuration
3. Review HTTP headers
4. Examine source code
5. Check for custom error pages
Do 404 errors show custom page?
Do 500 errors show custom page?
Or do they show server defaults?
6. Review configuration files
Are debug flags enabled in production?
Are error logs verbose?
Is sensitive data logged?
Mitigation Strategies
Create custom error pages
Log errors server-side, not to user
Remove debug code in production
Hide version information
Sanitize error messages
Never log sensitive data
Remove credentials from code
Use environment variables
Use secrets management
Use configuration files (not in git)
Use credential providers
Code review
Review all error handling
Check for debug statements
Verify no credentials in code
Ensure custom error pages used
Last updated