--- name: source-analysis description: Frontend source code analysis for hidden routes, API endpoints, and secrets origin: RedteamOpencode --- # Source Code Analysis ## When to Activate - After recon identifies target's web pages and JS/CSS files - SPA framework detected (React, Vue, Angular) - Directory fuzzing sparse — source analysis reveals paths fuzzing misses - GraphQL/REST API schema discovery needed ## Tools `run_tool curl`, `grep`/`sed`/`awk`, `jq` ## Local Artifact Guardrails When the task already provides a saved batch file or engagement workspace artifacts, prefer the local files over re-fetching remote content. - Start from the saved batch file, then inspect only the directly linked local artifacts you actually need. - For `page` batches, read the saved HTML/headers first, then only the specific JS/CSS files referenced by that page. - If a saved case or adjacent crawl metadata shows a concrete in-scope asset returned successfully but the engagement-local body is missing or empty, do one bounded recovery fetch of that exact URL back into the engagement workspace before declaring the case unanalyzable. - For concrete client-rendered page cases (`/#/...`, `#/...`, or other fragment routes preserved from bundle analysis), plain HTTP refetch of the same URL is not enough because it only replays the root document. Materialize those cases with `./scripts/katana_route_capture.sh "$DIR" ""` and inspect the saved route-capture artifact before marking the route exhausted. If the artifact only contains the exact-route seed error (for example `hybrid: response is nil`) or otherwise has zero successful response rows, treat that as failed materialization and requeue the route instead of closing it. - If route materialization proves the exact client screen exists (for example a route-specific lazy chunk/module loads, a distinct form/panel renders, or the capture shows a concrete stored/render sink), do **not** close the route family just because no brand-new requestable HTTP endpoint appeared. Preserve the exact route as a live `dynamic_render`/`auth_entry` follow-up and name the concrete UI/render action that still needs to be exercised (for example an exact `./scripts/browser_flow.py --url ... --output-dir ... [--cookies-from-auth "$DIR/auth.json"]` step, plus a tiny `--steps-file` when a specific control/form is already evidenced). After route-capture has already proven the exact page exists and you have named that first concrete `browser_flow.py` step, the source-analysis page case itself is exhausted unless new source artifacts arrive that materially change the route evidence. Do **not** keep sending the same page case back through source-analysis just to wait for the first live route execution. That first bounded browser-flow pass belongs to exploit-developer or another live-route execution owner. If that exact route has already been materialized with route-capture and then covered once with bounded `browser_flow.py`, and the only remaining blocker is missing auth/credentials or a later exploit/surface step that is already preserved as a concrete surface record, do **not** keep requeueing the same source-analysis case just to wait. Mark the queue row exhausted and leave the unresolved work on the tracked `dynamic_render` / `auth_entry` / workflow surface instead; otherwise the dispatcher can starve on the same auth-gated route forever. If saved route-capture/browser-flow evidence already shows a successful write-capable workflow or submission (redirect, success snackbar/toast, confirmation dialog, created record, or another distinct post-submit state), that is still not terminal coverage: keep the exact route/workflow alive for exploit and name one bounded abuse replay on the same workflow (duplicate/second submission first, then one evidence-grounded empty/boundary/forged/unauthorized variant when it fits the visible controls or auth context). When the evidence gives you human-visible cues (button text, field labels, placeholders) but not stable selectors, say so explicitly and prefer text-based browser-flow steps such as `click_text`, `type_by_label`, `type_by_placeholder`, `select_by_label`, or `submit_first_form` in the follow-up you hand back. When a visible `