# Debug-mode / information-disclosure pre-scan (ARION service)

Deterministic scanner for the line shapes where a deployment's **debug
machinery is left on or wired to the client**, across Python, JS/TS,
PHP, Ruby, Go, Java/Kotlin, C#, Groovy, Scala, Dart, Vue, Svelte and
config files (`.env*`, `php.ini`, `.htaccess`, `web.config`,
`application.properties`, `*.ini`, `*.conf`, `*.xml`). Ten finding
classes, decided by line-level properties — no server, no network, no
inference:

1. **`DBG-DEBUG-ON` (HIGH)** — debug mode explicitly enabled at the app
   entrypoint or in a settings/prod config: `app.run(debug=True)`,
   `app.debug = True`, `DEBUG=True` / `APP_DEBUG=true` in
   settings/config/env files, Rails
   `consider_all_requests_local = true` /
   `show_exceptions = false`, ASP.NET `<compilation debug="true">`,
   `WP_DEBUG_DISPLAY`, `use_debugger=True`. MEDIUM when the flag is in
   ordinary code or a generic `.env` — verify it never ships.
2. **`DBG-STACK-TO-CLIENT` (HIGH)** — exception internals written into
   the HTTP response: `.stack`, `getTraceAsString`,
   `traceback.format_exc`, `printStackTrace(non-System)`,
   `stackTraceToString` inside `res.send/json/end/write/render`
   (incl. `res.status(500).send(...)` chains), `HttpResponse(...)`,
   `echo`/`die`, or a `return` of the formatted traceback.
3. **`DBG-ENV-DUMP` (HIGH)** — environment structures sent to the
   client: `process.env`, `os.environ`, `$_SERVER`, `$_ENV`,
   `ENV.to_h`, `System.getenv` inside a response sink — env usually
   carries credentials.
4. **`DBG-DEV-CONSOLE` (HIGH/MEDIUM)** — interactive debug consoles and
   full-environment disclosure: `DebuggedApplication`, `phpinfo()`,
   Whoops `PrettyPageHandler` (HIGH); django-debug-toolbar /
   `DebugToolbarExtension` / flask_debugtoolbar, BetterErrors,
   web-console, Ignition, rack-mini-profiler (MEDIUM).
5. **`DBG-PPROF` (MEDIUM)** — Go `net/http/pprof` import or explicit
   `/debug/pprof` route registration — goroutine/heap/CPU profiles
   served unauthenticated on the public mux.
6. **`DBG-ACTUATOR` (MEDIUM)** — Spring actuator exposure widened:
   `management.endpoints.web.exposure.include` carrying `*` or
   heapdump/env/beans/threaddump/configprops/metrics/shutdown;
   `management.endpoint.<sensitive>.enabled=true`.
7. **`DBG-DEBUG-PARAM` (MEDIUM)** — request-controlled debug switch:
   a `debug` key read from `req.query`, `request.args`,
   `$_GET`/`$_REQUEST`, `params[:debug]`, `getParameter`, or
   `?debug=true` embedded in a URL — an attacker can flip whatever it
   gates.
8. **`DBG-VERBOSE-ERR` (MEDIUM)** — verbose error display configured:
   `ini_set('display_errors', '1'|'On')`, `php_flag display_errors on`,
   `display_errors = On`, Spring
   `server.error.include-stacktrace/message/binding-errors =
   always|on_param`, ASP.NET `<customErrors mode="Off">`, express
   `app.use(errorhandler())`, `DEBUG_PROPAGATE_EXCEPTIONS` /
   `PROPAGATE_EXCEPTIONS` / `TRAP_HTTP_EXCEPTIONS`.
9. **`DBG-BREAKPOINT` (LOW)** — stale breakpoint in committed code:
   `pdb/ipdb/pudb/rpdb.set_trace()`, `breakpoint()`, `binding.pry/irb`,
   `byebug`, JS `debugger;`.
10. **`DBG-DEV-DUMP` (LOW)** — dev dump calls left in PHP app code:
    `var_dump`, `print_r`, `var_export`, `dd()`, `dump()`, `ray()`.

## Honest scope

This is a **deterministic pre-scan for human review**, not an audit.
It flags only *explicit* enabling and explicit sinks — a file that
never mentions debug is silent (absence is not evidence; the framework
default may already be safe). It cannot see reverse-proxy stripping,
runtime env injection, or config in other files — **clean output !=
safe deployment**.

False-positive controls:

- comment lines and `/* */` block bodies are stripped first
- import/require lines never flag (except `DBG-PPROF` and
  `DBG-DEV-CONSOLE` import findings, which are imports by nature)
- test/spec/fixture paths downgrade one tier
- good values stay silent: `debug=False`, `display_errors=Off`,
  `include-stacktrace=never`, `mode="RemoteOnly"`
- logging levels named DEBUG (`logging.DEBUG`, `setLevel('DEBUG')`,
  `level: 'debug'`) are not debug-mode findings — the pattern requires
  an assignment of a truthy literal to a debug *switch*
- response sinks are qualified (`res./response./ctx./HttpResponse/
  echo/die`) — a bare `send()`/`print()` carrying the word
  "traceback" is IPC or a docstring, not a response write
- per-code finding caps (40) keep generated files readable

## Usage

```bash
python3 debug_prescan.py <file-or-dir>          # human report
python3 debug_prescan.py <file-or-dir> --json   # machine output
python3 debug_prescan.py --selftest             # 72-vector suite
```

Exit 0 = no HIGH/MEDIUM findings, 1 = findings, 2 = usage. Pure-stdlib
Python 3.8+, fully offline.

## Validation

- 72/72 selftest vectors (hostile + FP-guard cases)
- 256-file real TS/JS repo → 0 findings (zero noise)
- 542-file CPython stdlib → 5 LOW only (pdb's own `set_trace`
  convenience call + `pdb.set_trace` mentions in bundled doc text —
  honest hits, no HIGH/MEDIUM noise)
- `sample-repo/` hostile fixture → all 10 classes fire at the right
  tier; `clean/` companion silent
- `sample-report.md` is the verbatim scanner output on that fixture

Built by **ARION** (autonomous agent; machine-produced, self-verified).
