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 = 1

What the attacker learns:

  1. Database is MySQL (version from error)

  2. Exact SQL query structure: SELECT * FROM products WHERE name LIKE '%[INPUT]%' AND active = 1

  3. SQL injection is possible (query error shows uncaught exception)

  4. There's an active field (logic discovery)

  5. 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:

  1. Web root is /var/www/html (server architecture)

  2. File structure:

    • /api/user.php - handles user API

    • /src/User/Manager.php - user management logic

    • /api/router.php - routing logic

  3. Code flow: How requests are routed and processed

  4. Function names: handleRequest(), getUserProfile() (API endpoints)

  5. PHP version and framework (error format)

  6. Exact line numbers where errors occur

The attack:

With this knowledge, attacker:

  1. Enumerates file structure

  2. Tests each API endpoint knowing exact code paths

  3. Identifies vulnerable functions

  4. 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:

  1. Emails - User enumeration (who has accounts)

  2. Password hashes - Can be cracked offline

  3. API keys - Direct service access

  4. Database credentials - Database compromise

  5. Full user objects - All user data exposed

The attack:

Attacker:

  1. Captures API response with full user object

  2. Gets user's API key

  3. Uses API key to access other services

  4. Accesses password hash, runs offline crack

  5. 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:

  1. Apache 2.4.41 - Version with known CVEs

  2. PHP 7.4.3 - Version with known vulnerabilities

  3. Laravel 8.12.0 - Framework version with known exploits

  4. Application structure - Uses Models (Laravel MVC)

The attack:

Attacker:

  1. Looks up CVE-2020-xxxx for Apache 2.4.41

  2. Finds public exploit for PHP 7.4.3

  3. Searches Exploit-DB for Laravel 8.12.0

  4. Finds remote code execution vulnerability

  5. 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:

  1. Debug credentials: admin / AdminDebug123!

  2. Database credentials: User and password

  3. Database server: db.internal.company.com

  4. Database name: prod_db

  5. Port: 5432

The attack:

Attacker:

  1. Uses debug credentials to log in as admin

  2. Or uses database credentials to connect directly to PostgreSQL

  3. Dumps entire database

  4. 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