Stack traces and dependency versions leaked in 500 responses
Multiple (any unhandled exception path)
description
Unhandled server exceptions return HTTP 500 responses containing the full Python stack trace, source file paths revealing the deployment layout, and the exact versions of installed dependencies. The traces include framework internals (`/app/venv/lib/python3.11/site-packages/django/...`) and application module paths. The disclosed versions of `django`, `cryptography`, and `pillow` include CVEs published within the last 90 days. Stack traces also include local variable contents at the frame of failure, in some cases leaking partial request bodies.
evidence
Request
POST /api/orgs/invite HTTP/1.1
Host: acme.dev
Authorization: Bearer <session-token>
Content-Type: application/json
{"email":null}
Response
HTTP/1.1 500 Internal Server Error
Content-Type: text/html
Server: gunicorn/21.2.0
Traceback (most recent call last):
File "/app/api/views/orgs.py", line 142, in invite
domain = email.split("@")[1].lower()
AttributeError: 'NoneType' object has no attribute 'split'
Local vars:
request = <Request POST /api/orgs/invite>
email = None
inviter_id = 'usr_4421'
Django 4.2.7 · Python 3.11.6 · cryptography 41.0.5
reproduction steps
- Send any request that triggers an unhandled exception (passing null where a string is expected works on the invite endpoint).
- Observe a 500 response containing the full Python traceback, source paths, dependency versions, and local variable contents.
remediation
Disable debug output in production: a global exception handler returns a generic 500 with an opaque reference id while full traces go to your observability backend. Fail CI on a debug build, and patch the disclosed dependency versions.
python
# settings/production.py DEBUG = False ALLOWED_HOSTS = ['acme.dev'] # handler500 logs the traceback server-side and renders a generic page
rotate the credentials you provided.
we ran the scan with the credentials you supplied. treat them as compromised and rotate now.
couldn't reproduce this finding?
if it does not reproduce from the evidence above, you get back what this finding cost you: its credits for a credit unlock, or a cash refund for a finding bought through our earlier per-finding checkout. see how claims work, or email team@recon.sh with finding ID f5 and scan ID sample.