Verbose errors: hide stack traces behind a clean error page
Returning generic error pages in production stops your app from printing internal paths, queries, and versions to visitors
The threat
The scanner triggered an error on your site and got back a detailed diagnostic page: a stack trace, file paths like /var/www/app/models/user.rb, framework and version banners, sometimes the exact database query that failed. That page is meant for you, during development. In production, it went straight to the public.
To an attacker it reads like a free orientation session. The file paths reveal your directory layout, the version banners tell them what to look up exploits for, and a leaked SQL statement hints at your table names and where an injection might land. They didn’t have to probe for any of it, the error volunteered it.
The exact fix
Two parts, whatever the stack: run the framework in production mode so it stops rendering debug pages, and serve your own generic 404 and 500 pages while the real details go to a server-side log.
Turn off debug mode for your framework:
# Node / Express
NODE_ENV=production # disables the dev error handler and stack traces
# Flask: never run with debug=True in production
app.run(debug=False)
# Django: settings.py
DEBUG = False # (and set ALLOWED_HOSTS)
# Rails: config/environments/production.rb
config.consider_all_requests_local = false
<!-- ASP.NET: web.config -->
<customErrors mode="On" defaultRedirect="~/error" />
Then serve a custom error page so visitors and bots get something friendly and blank of detail. On nginx you can backstop it at the server too:
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
The details aren’t useless, they’re just for you. Keep full stack traces flowing to a server-side log or an error-tracking service (Sentry, CloudWatch, a plain log file), so you lose nothing when debugging. The only change is that the public sees a clean page while the trace goes somewhere private.
Verify it
curl -s https://yourdomain.com/does-not-exist-12345 | grep -iE 'stack trace|traceback|exception|on line [0-9]'
Request a broken or malformed path, then check the response. A correct result is your own tidy error page and no output from that grep: no traceback, no file paths, no exception class names. Any of those still showing means debug mode is on somewhere.
Proof
Confirmed by a page rendering a framework or SQL stack trace, the ApeCyber scanner catches that passively, from the outside, touching nothing. apecyber.com and dev3lop.com both return clean, generic error pages and grade A / 100, so an attacker gets no paths, versions, or queries to work from. Flipping to production mode is a 10-minute, −10 fix that gives away nothing your logs don’t already capture privately.