In one paragraph
A stack trace exposed on an error page reveals internal debugging details to visitors. It may disclose file paths, queries, framework information, or sensitive request context. Return a controlled error response and record useful diagnostics in protected server-side logs instead. Investigate what was actually exposed; a detected trace is information disclosure, not automatic proof that the application was compromised.
Why it matters
Debug output is designed to help developers understand a failure. It can also help an attacker identify components, map internal code paths, or refine further probes. Some interactive debug interfaces expose substantially more capability than a plain trace, so investigate whether a debugger is reachable as well as whether text appears.
The finding does not establish the root cause. A production debug setting is one possibility, but an application can also deliberately render an exception, a proxy can expose its own diagnostics, or an ordinary tutorial can contain a matching example. Review the URL and evidence rather than inferring the entire deployment configuration from a text match.
Error handling has two audiences. Visitors need a safe explanation and a way forward; maintainers need enough context to investigate. Removing public details without retaining useful protected diagnostics trades one problem for another.
How WebAuditOS evaluates this finding
The supplied check searches parsed HTML in the title, H1 headings, and body for known debug-output patterns. A recognised pattern fails; no match passes. Responses that are not parsed as HTML are not graded. Title and heading matches take priority over body matches in the reported evidence.
Recognised families include Python traceback banners, Java and Node stack frames, PHP messages with file and line details, SQLSTATE codes, ASP.NET error screens or frames, Go panic output, and a Laravel error-page phrase. This is a fixed-pattern detector, not a runtime-aware guarantee.
Some educational content can contain those same signatures. A trace with no recognised markers, a JSON API response, or a route outside the crawl can remain undetected. Passing means no known pattern was found in the inspected pages, not that every failure path is safe.
How to fix it
- Reproduce the reported response safely. Inspect the exact URL and matched text while signed out. Determine whether the content is an actual error, intentional documentation, or a false positive. Use staging for deliberate failure tests that could affect production data.
- Identify the layer exposing details. Application middleware, a framework debug page, a reverse proxy, and an API serialiser can require different fixes. Search for the actual matched text or exception-rendering path.
- Disable visitor-facing debug output in production. Examples include DEBUG=False in Django, APP_DEBUG=false in Laravel, and display_errors=Off in PHP. Apply the framework's full deployment guidance: changing one environment variable does not guarantee every custom handler stops rendering sensitive details.
- Add a central unexpected-error handler. Return a generic HTML page or a stable API error object, while recording an internal diagnostic event. Give the visitor a non-sensitive reference identifier that can be correlated with the log. Do not echo stack frames, SQL statements, environment variables, or secrets.
- Preserve meaningful HTTP status codes. Missing resources should normally remain 404, and unexpected server failures should return an appropriate 5xx status. A friendly error template must not accidentally return 200 for every failure or redirect all errors to the homepage.
- Protect the logs too. Restrict access and retention, redact credentials and tokens, and avoid blindly storing complete request bodies. Diagnostic logs can become another exposure if they contain sensitive data or are served from a public directory.
- Test representative failure paths. Include a missing URL, a controlled application exception, invalid input, permission denial, and a JSON endpoint. Check signed-out and authenticated behaviour as appropriate. Confirm that the client receives a safe message and the internal event is available to the right team.
- Rescan the reported HTML URLs and keep regression tests around error formatting. A single corrected page does not prove the API or another service uses the same handler.
What the fix can break
Removing public debugging can slow investigation if logging and correlation are not ready. Set up the diagnostic path before the rollout. Development can retain detailed errors locally; shared test environments should also avoid exposing secrets or unrestricted debuggers.
Changing response bodies may break clients that parse free-form exception text. Give APIs documented error codes and a stable schema rather than preserving leaked internals for compatibility.
Error templates can themselves fail or rewrite statuses incorrectly. Keep them simple, verify actual responses, and ensure monitoring still detects server failures. A branded page is useful only if it does not disguise an outage as a successful response.
Questions
Does an exposed stack trace prove a hack happened?
No. It demonstrates, or suggests, unintended diagnostic disclosure. Review the actual data and any reachable debug functionality, then assess whether an incident investigation is warranted.
Should every error return the same HTTP code?
No. Keep useful status distinctions such as 404, 403, and 5xx where appropriate without exposing internal implementation details. Safe messages and correct statuses can coexist.
Why did an API trace not appear in this finding?
The documented rule inspects parsed HTML. JSON and other response formats need separate tests even if they expose equivalent internal information.
Which related checks help?
Review directory listing for public files and exposed X-Powered-By headers for another disclosure signal. Fixing either does not replace safe error handling.