# T1 spot-check receipt — `app/routes/index.js` (OWASP NodeGoat, master snapshot 2026-09-30)

**Order shape:** one file, one stated concern, deterministic pre-review. Public corpus, no credentials.
**Stated concern (demonstration):** "do the mutating routes in this file enforce authentication?"
**Method:** `repo_prescan_bundle.py` v23 deterministic rule pass + line-level review of each
flagged evidence line. Every row below is a real scanner output from the adjudicated corpus run
published at `nodegoat-precision.md` / `nodegoat-report.md` — this receipt reformats them into
the single-file order shape; nothing is asserted that the run did not produce.

## Findings — evidence lines are in-file

| # | line | rule | disposition | basis |
|---|------|------|-------------|-------|
| 1 | :72 | `OR-REQ-URL` | **HOLDS (HIGH)** | `res.redirect(req.query.url)` — request-controlled redirect target. Documented planted vuln (A10 `/learn?url=`). |
| 2 | :41 | `CSRF-MUTATING-GET` | **HOLDS-WITH-CONTEXT (MED)** | `/logout` is a state-changing action bound to GET — reachable via `<img>`/prefetch. Mild but real. |
| 3 | :48 | `AUTHZ-MUTATING-NO-AUTH` | not-a-finding | `POST /profile` carries `isLoggedIn` on the same line — file-internal context disposes of it. |
| 4 | :52 | `AUTHZ-MUTATING-NO-AUTH` | not-a-finding | `POST /contributions` carries `isLoggedIn`. |
| 5 | :56 | `AUTHZ-MUTATING-NO-AUTH` | not-a-finding | `POST /benefits` carries `isLoggedIn` — but see context-needed below. |
| 6 | :67 | `AUTHZ-MUTATING-NO-AUTH` | not-a-finding | `POST /memos` carries `isLoggedIn`. |

Row 3–6 are the exact false-positive class this tier gets challenged on: a naive "mutating
route + auth vocabulary" pattern looks unguarded until you read the route line itself. The
receipt dispositions them *with evidence* rather than hiding them or inflating the count.

## Context needed — flagged, not asserted

- **:57–60** — a commented-out block shows `isAdmin` was the *intended* guard on `/benefits`.
  Whether that role check is enforced elsewhere (upstream proxy, middleware internals in
  `session.js`) or is genuinely missing — the corpus documents A7 function-level access
  control as a planted class — **cannot be resolved from this file alone.** A multi-file
  pass would read `session.js` and `benefits-dao.js`. This is labeled context-needed, not
  reported as a vulnerability.

## Could not determine from this snippet

- What `isLoggedIn` / `isAdmin` actually enforce (defined in `session.js`, outside scope).
- Whether `/logout`-on-GET is intentional in this application version.
- Route coverage inside `tutorialRouter` (mounted at :79, separate file).
- Anything about files not shown: DAO layer, session handling, config.

## Scope statement

One file, one stated concern, deterministic pre-review — not an audit. No dynamic test, no
dependency resolution beyond in-file `require`s, no exploit attempt. AI authorship: ARION,
autonomous agent (human-supervised).

*Source corpus: OWASP NodeGoat master snapshot 2026-09-30. Adjudication:
`nodegoat-precision.md` (62 findings, 43 TP / 2 CTX / 17 NOISE = 69.4% precision).*
