Severity: Critical (CVSS ~8.1)
Summary
Debug mode is enabled by default (debug: bool = True), and when an unhandled exception occurs, the full Python traceback — including internal file paths, variable values, and any data captured in exception messages — is served as raw, unescaped HTML. This creates a Reflected XSS vulnerability and full stack trace information disclosure in production deployments.
Vulnerable Code
backend/secuscan/config.py:22 — Debug defaults to True:
backend/secuscan/main.py:277-289 — Unescaped traceback in HTML response:
@app.exception_handler(Exception)
async def custom_unhandled_exception_handler(request: Request, exc: Exception):
logger.exception("Unhandled exception in request lifecycle")
if settings.debug:
import traceback
html = f"<html><body><h1>500 Internal Server Error</h1><pre>{traceback.format_exc()}</pre></body></html>"
response = HTMLResponse(html, status_code=500)
else:
response = PlainTextResponse("Internal Server Error", status_code=500)
Attack Vector
Reflected XSS
- Attacker crafts a request that causes an unhandled exception where the exception message contains attacker-controlled HTML/JS (e.g., via a plugin ID, target URL, or header value that propagates into an exception)
- The
traceback.format_exc() output is embedded directly into HTML with no escaping
- If any variable in the traceback chain contains attacker-controlled content, arbitrary JavaScript executes in the victim's browser
Information Disclosure (independent of XSS)
Even without XSS exploitation, the stack trace exposes:
- Full server filesystem paths (e.g.,
/app/secuscan/executor.py)
- Python version and installed packages
- Internal variable names and data structures
- Potentially sensitive values captured in local variables at exception time
Additional Debug Mode Risks
main.py:332 — API docs URL exposed in root response when debug=True
main.py:171-173 — OpenAPI schema publicly accessible (/openapi.json, /docs, /redoc) when debug is enabled
routes.py:241-242 — Plugin metadata reloaded from disk per-request in debug mode — filesystem manipulation risk
Impact
- Reflected XSS: Arbitrary JavaScript execution in victim's browser context
- Full information disclosure: Internal paths, variable names, package versions leaked
- Production risk: Default
debug=True means production deployments are vulnerable unless explicitly configured
- Attack surface expansion: Exposed OpenAPI docs reveal all endpoints for further attacks
Recommended Fix
- Set
debug: bool = False as the default — debug mode should be opt-in via explicit environment variable
- HTML-escape
traceback.format_exc() before embedding in HTML response:
import html
escaped = html.escape(traceback.format_exc())
html_content = f"<html><body><h1>500 Internal Server Error</h1><pre>{escaped}</pre></body></html>"
- Use a structured error response instead of raw HTML in the exception handler, even in debug mode
- Gate OpenAPI/docs endpoints behind debug mode — disable
/docs, /redoc, /openapi.json when debug=False
Severity: Critical (CVSS ~8.1)
Summary
Debug mode is enabled by default (
debug: bool = True), and when an unhandled exception occurs, the full Python traceback — including internal file paths, variable values, and any data captured in exception messages — is served as raw, unescaped HTML. This creates a Reflected XSS vulnerability and full stack trace information disclosure in production deployments.Vulnerable Code
backend/secuscan/config.py:22— Debug defaults to True:backend/secuscan/main.py:277-289— Unescaped traceback in HTML response:Attack Vector
Reflected XSS
traceback.format_exc()output is embedded directly into HTML with no escapingInformation Disclosure (independent of XSS)
Even without XSS exploitation, the stack trace exposes:
/app/secuscan/executor.py)Additional Debug Mode Risks
main.py:332— API docs URL exposed in root response whendebug=Truemain.py:171-173— OpenAPI schema publicly accessible (/openapi.json,/docs,/redoc) when debug is enabledroutes.py:241-242— Plugin metadata reloaded from disk per-request in debug mode — filesystem manipulation riskImpact
debug=Truemeans production deployments are vulnerable unless explicitly configuredRecommended Fix
debug: bool = Falseas the default — debug mode should be opt-in via explicit environment variabletraceback.format_exc()before embedding in HTML response:/docs,/redoc,/openapi.jsonwhendebug=False