Codex agent — after remediation

Codex agent remediation result

  1. Generated. codex wrote this application during this run, from a prompt. Not written by a human, and not selected for being vulnerable. The prompt and generated code browser are linked below.
  2. Insecure. REACHABLE found the remediation list — all findings that are not proven noise. See the scan.
  3. Remediated. REACHABLE handed that remediation list to the same agent. The final scan has 7 open actionable finding(s); 0 resolved against the baseline scan.

Application evidence: generation prompt · workspace contents · code before remediation · fixed code · side-by-side code diff

Model disclosure: the application was written by gpt-5.5 from OpenAI API, pinned for this run and recorded in the run's evidence. The fix was made by the same agent, but through reachctl remediate, which selects the agent and does not pin its model — so the fixing model is whichever that agent's CLI resolved at run time, and is not asserted here.

Scanner provenance

REACHABLE wheel/build and scan timestamps, read from the scanner database rows that produced the page. Actionable counts are repo.db SIGNAL rows under the product ACTIONABLE_SQL filter.

ScanREACHABLE versionTimestamp (UTC)CommitStatusActionable
Baseline1.0.0b1992026-09-12 14:17:0348eb92fcsuperseded7
Baseline1.0.0b1992026-09-12 14:21:2948eb92fcsuperseded8
Baseline1.0.0b1992026-09-12 15:19:2348eb92fccomplete7

Run estimate

Token estimates are recorded before the run starts. The remediation estimate is recalculated after REACHABLE has the scan database and knows how many findings are in scope.

Planned runtime21-110 minutes
Planned model tokens53000-475000 total
Planned input tokens28000-280000
Planned output tokens25000-195000
Generation budget1800s
Remediation scope7

Run 2026-09-12 14:21:45 UTC · status partial after 2 agent fix attempt(s)

INITIAL SCOPE
7
repo.db actionable (baseline)
CURRENT OPEN
7
repo.db actionable (final scan)
RESOLVED
0
scan delta (initial − open)

Run status: partial after 2 iteration(s).

Initial actionable (repo.db): 7. Resolved (scan delta): 0. Current open (repo.db): 7. Noise (repo.db baseline): 24. INITIAL, OPEN, and RESOLVED come from repo.db actionable counts (product ACTIONABLE_SQL on the baseline and final scans). They are not counted from SARIF, data.json, or remediation-audit row matching. The table below is the per-finding remediation ledger.

Open means still actionable on the final scan in repo.db. That can mean the iteration budget ended, the agent did not make the right change, or the finding needs a non-source/package/build change that the agent could not safely complete in this lane. Per-finding ledger rows below may still disagree with this scan total when matching is incomplete; the cards follow the database.

Generated workspace contents

The agent generated these files in the repository before scan. They are scanned and published as evidence. Dependency installs, build outputs, and compiled binaries can explain why one agent has more package or binary findings than another.

Workspace observations: binary_artifact: 12, build_directory: 1735, compiled_artifact: 9, extensionless_executable: 12. Open the full JSON.

Largest generated fileBytes
portal/node_modules/esbuild/bin/esbuild11427952
portal/node_modules/@esbuild/linux-x64/bin/esbuild11427952
portal/node_modules/.bin/esbuild11427952
portal/node_modules/better-sqlite3/deps/sqlite3/sqlite3.c9234104
portal/node_modules/typescript/lib/typescript.js9112572

Remediation scope — 7 finding(s)

repo.db actionable count on the baseline scan. Table lists 7 ledger/validation row(s) as per-finding evidence.

OrderOutcomeSeverityTypeFindingFile
1Not fixedCRITICALCWEUser-controlled path joined into filesystem path - path traversal riskportal/src/server.ts:116
2Not fixedCRITICALCWEFlask route sends a non-literal file path — path traversal riskdocs-worker/app.py:126
3Not fixedHIGHCWESQL query with f-string interpolation — SQL injection riskdocs-worker/app.py:139
4Not fixedHIGHCWESQL query built with string concatenation — use PreparedStatement with parameterized queries instead.risk-api/src/main/java/com/sthenos/treasury/RiskApi.java:184
5Not fixedMEDIUMCWEFile read on a path built from external input without resolving symlinks and validating the result stays inside the expected directory — CWE-59 symlink following. An attacker who controls the directordocs-worker/app.py:140
6Not fixedLOWCONFIGFound an HTTP server without TLS. Use 'http.ListenAndServeTLS' instead. See https://golang.org/pkg/net/http/#ListenAndServeTLS for more information.payments-api/main.go:51
7Not fixedLOWCVEGHSA-68rp-wp8r-4726docs-worker/app.py:89

This is the remediation list REACHABLE handed to the agent, collapsed to each finding's final recorded outcome. The noise list below is excluded only when REACHABLE has explicit non-production or unreachable evidence.

The code the agent wrote

The staged patch, exactly as committed.

The agent changed no files. The diff was produced and is empty, so this is a measured outcome and is published as such.

Noise — 22 finding(s)

All 22 are excluded for one reason: the application never reaches the vulnerable code. These are real advisories against real dependencies — not filtered out as test or scaffolding files. They are excluded from the remediation scope, and listed rather than hidden. 1 of 22 stopped appearing once the in-scope fixes landed, almost always because they shared a root cause with something that was in scope. REACHABLE never asked the agent to touch them and they are not counted as fixed — the point of excluding them is that they did not need fixing. The other 21 are unchanged.

What happenedWhy it is excludedSeverityTypeFindingFile
Not fixednot reachableHIGHCVEGHSA-535w-7cp7-47q4agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
Not fixednot reachableHIGHCVEGHSA-fjgf-rc76-4x9pagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
Not fixednot reachableHIGHCWEUser-controlled value interpolated into a query string via fmt.Sprintf — potential code injection (CWE-94). The interpolated value may allow arbitrary query commands. Use parameterized queries or striagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/payments-api/main.go
Not fixednot reachableHIGHDLPPII data sent to external HTTP endpoint — data leakage risk.agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/payments-api/main.go
Not fixednot reachableHIGHCVEGHSA-wc9g-mqfw-jrwmagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
Not fixednot reachableHIGHCVEGHSA-xf7r-hgr6-v32pagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
Not fixednot reachableHIGHCVEGHSA-44fp-w29j-9vj5agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
Not fixednot reachableHIGHCVEGHSA-g5hg-p3ph-g8qgagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
Not fixednot reachableHIGHCVEGHSA-5528-5vmv-3xc2agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
Not fixednot reachableHIGHCWESQL query with f-string interpolation — SQL injection riskagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/docs-worker/app.py
Not fixednot reachableHIGHCVEGHSA-72gw-mp4g-v24jagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
Not fixednot reachableHIGHCVEGHSA-v52c-386h-88mcagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
Not fixednot reachableHIGHCWESQL query built with fmt.Sprintf — SQL injection riskagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/payments-api/main.go
Not fixednot reachableHIGHCVEGHSA-4pg4-qvpc-4q3hagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
Not fixednot reachableMEDIUMCWEInternal error details written to HTTP response — exposes server internals (table names, paths, stack traces) to clients. Return a generic error message and log the detail server-side.agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/payments-api/main.go
Not fixednot reachableMEDIUMCWEInternal error details written to HTTP response — exposes server internals (table names, paths, stack traces) to clients. Return a generic error message and log the detail server-side.agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/payments-api/main.go
Not fixednot reachableMEDIUMCWEHTTP response status code is never checked. 4xx/5xx errors and 3xx redirects are silently treated as successful responses, potentially processing error pages as valid data (CWE-391). Add: if resp.Statagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/payments-api/main.go
Not fixednot reachableMEDIUMCWEInternal error details written to HTTP response — exposes server internals (table names, paths, stack traces) to clients. Return a generic error message and log the detail server-side.agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/payments-api/main.go
Not fixednot reachableMEDIUMCWEUnbounded read of HTTP response body — DoS via large response. Wrap with io.LimitReader: io.ReadAll(io.LimitReader(resp.Body, maxBytes))agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/payments-api/main.go
Not fixednot reachableMEDIUMCWEInternal error details written to HTTP response — exposes server internals (table names, paths, stack traces) to clients. Return a generic error message and log the detail server-side.agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/payments-api/main.go
Not fixednot reachableLOWCVEGHSA-qvfw-j98x-7q72agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
Gone, not attributednot reachableINFOSUSPICIOUSNew dependency not present in prior version (6.15.2): es-define-propertypkg://qs@6.15.3

Additional scan context — 9 row(s)

Not remediation scope and not counted as noise. These rows were present in scanner context but were not in the product's actionable validation export for this source-remediation pass, so they are not counted as fixed or open remediation work.

Why it is not in scopeSeverityTypeFindingFile
reachable, marked not actionableCRITICALCWEUser-controlled path joined into filesystem path - path traversal riskagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
reachable, marked not actionableCRITICALCWEFlask route sends a non-literal file path — path traversal riskagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/docs-worker/app.py
reachability not establishedHIGHCWESQL query built with string concatenation — use PreparedStatement with parameterized queries instead.agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/risk-api/src/main/java/com/sthenos/treasury/RiskApi.java
reachable, marked not actionableHIGHCWESQL query with f-string interpolation — SQL injection riskagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/docs-worker/app.py
reachable, marked not actionableMEDIUMCWEFile read on a path built from external input without resolving symlinks and validating the result stays inside the expected directory — CWE-59 symlink following. An attacker who controls the directoragent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/docs-worker/app.py
reachability not establishedMEDIUMCWEExpress app without helmet - missing security headersagent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/portal/src/server.ts
reachable, marked not actionableLOWCONFIGFound an HTTP server without TLS. Use 'http.ListenAndServeTLS' instead. See https://golang.org/pkg/net/http/#ListenAndServeTLS for more information.agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/payments-api/main.go
reachable, marked not actionableLOWCVEGHSA-68rp-wp8r-4726agent-remediation/workspace-remediation/20260912-142126/iteration-02/proof-state/scanner-v0/docs-worker/app.py
reachability not establishedINFOSUSPICIOUSNew dependency not present in prior version (10.9.2): picocolorspkg://jake@10.9.4

Remediation Attempt

Started with 7 findings to fix. Iteration 2 fixed 0 issues; 7 issues left. 7 finding(s) still need attention.

7 security finding(s) still remain. Noise and context are listed separately on this page.

Starting findings7
Iterations used1
Final open findings7
Noise excluded0
Context only0
Stop conditionStopped with findings still open.

Pass-by-pass breakdown

PassStarted withFixedLeftNoise excludedContextTimeHow it ended
27070067.6sran to completion
Total7070067.6snone killed

Iteration 2: fixed 0 issues; 7 issues left

How long it took

Wall clock, read from the scanner's own output and the remediation database timestamps.

StageSeconds
Scan (before)180.3s
Rescan (after)169.1s
Agent pass 1 (writing the fix)14.1s
Agent pass 2 (writing the fix)14.6s
Remediation loop total (2 pass(es), incl. a rescan per pass)144.2s
Agent time only, all passes28.7s

← initial scan · this pipeline run