OWASP ASVS 7.4.1: Error Handling Without Information Disclosure - Java, Python, JavaScript

AI Tools

Introduction

OWASP ASVS requirement 7.4.1 addresses how applications respond when something goes wrong. A poorly handled error can return a full stack trace, database query, internal file path, or fragment of sensitive input back to the user - information attackers use to map the application's internals and identify further vulnerabilities. 7.4.1 requires that error messages returned to users and written to logs be generic, consistent, and free of information disclosure.

This page explains the requirement, shows common violation patterns, and provides remediation code in Java, Python, and JavaScript.

The requirement, in OWASP's words

ASVS v4.0.3: 7.4.1 Verify that a generic message is shown when an unexpected or security-sensitive error occurs, potentially with a unique ID which support personnel can use to investigate.

ASVS 5.0 moves this to requirement 16.2.1 with equivalent intent: error handling must not leak stack traces or internal implementation details.

Why this requirement exists

Information leakage enables further attacks. A stack trace reveals framework versions, internal class names, file paths, and sometimes SQL fragments. Attackers use this to identify known vulnerabilities in specific library versions or to craft more targeted injection payloads.

Error messages often echo user input. A validation error for an email field might include the invalid value in the response: "Invalid email: [email protected]". When that value contains sensitive data (a mistyped password in the email field, for example), the error response becomes a data exposure.

Logged errors propagate sensitive data. Unhandled exceptions caught by a top-level handler often log the full exception chain. If any link in that chain includes sensitive input, it gets written to the log - overlapping directly with ASVS 7.1.1.

Remediation

The pattern is the same across languages: catch all unhandled exceptions at a global handler, generate a correlation ID, log the full exception internally with that ID, and return only the ID to the client. Implementation differs by framework:

  • Java: Centralize error handling through a @ControllerAdvice class (Spring) or a servlet-level error handler. Never return raw exception messages to the client.
  • Python: Register a global exception handler - @app.errorhandler(Exception) in Flask, app.add_exception_handler(Exception, handler) in FastAPI, or middleware with process_exception in Django.
  • JavaScript: Error-handling middleware must be the last middleware registered and must have an arity of four (err, req, res, next) to be recognized by Express as an error handler.
Java
Javascript
Python
Copy

Watch out for: logger.error("Failed to process: " + input, ex) - string-concatenating untrusted input into the log message can also violate 7.1.1 if input contains sensitive data. Pass input as a parameter and evaluate whether it should be logged at all.

Production flag: Frameworks like Express, Flask, and Django have debug/development modes that return detailed error pages. These are useful in development and dangerous in production. Verify that debug mode is disabled on production deployments - a common oversight that leads directly to 7.4.1 violations.

Common 7.4.1 violations we see in code

  • ** Returning exception.getMessage() to the client. Especially common in hand-rolled error handlers. Exception messages often contain SQL fragments, file paths, or serialized request data.
  • *
  • Default framework error pages in production. Django's DEBUG=True, Flask's debug mode, Express's default 500 handler - all return stack traces when misconfigured in production.
  • HTTP response headers revealing stack details. Some frameworks set X-Powered-By, Server, or custom debug headers that disclose implementation details.
  • Logging exceptions with untrusted input interpolated. logger.error(f"Failed to process {user_input}") can turn an error event into a PII exposure if user_input is sensitive.
  • Returning validation errors that echo invalid input. "Email '[email protected]' is not valid" discloses the submitted value, which may be sensitive if the user mistyped into the wrong field.

How HoundDog.ai detects 7.4.1 violations

HoundDog.ai's scanner detects three specific patterns that map to 7.4.1:

  • CWE-209: Generation of Error Message Containing Sensitive Information. Flags when an exception message or error response includes data derived from sensitive inputs.
  • CWE-210: Self-Generated Error Message Containing Sensitive Information. Flags when application-generated error text (not raw framework output) includes sensitive data.
  • CWE-532 (overlap): Insertion of Sensitive Information into Log File. When 7.4.1 violations manifest as sensitive data written to error logs, the detection overlaps with 7.1.1 tooling.

The scanner integrates with IDE plugins (VS Code, Cursor, IntelliJ, Eclipse) and CI pipelines (GitHub Actions, GitLab CI, Azure Pipelines, CircleCI, Bitbucket Pipelines, Jenkins) to surface these issues during code review, before the code reaches production.

  • 7.4.2 - Error handling for defense in depth. Custom error handlers must catch otherwise uncaught exceptions to prevent default framework error pages.
  • 7.4.3 - Last-resort error handling. A last-line-of-defense handler must exist to ensure no unhandled exception reaches the user.
  • 7.1.1 - Logging sensitive data. When errors are logged, 7.1.1 applies to ensure sensitive data doesn't reach log files. Covered on our dedicated OWASP ASVS 7.1.1 page.
Type to search, ESC to discard
Type to search, ESC to discard
Type to search, ESC to discard