-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Bug: Stale deliverables from prior runs bleed into new reports #257
Description
Bug Description
When running Shannon against the same target repo multiple times (separate runs, not resume), stale exploitation evidence files from prior runs are picked up by assembleReportActivity() and included in the new report — even when the current run's vulnerability analysis found nothing to exploit.
Root Cause
assembleFinalReport() in src/services/reporting.ts:19-77 reads whatever *_exploitation_evidence.md files exist in {repoPath}/deliverables/. It does not verify whether those files were produced by the current run. Since deliverables are saved to the target repo's filesystem, files from a previous run persist across runs.
The pipeline does not clean {repoPath}/deliverables/ at the start of a fresh (non-resume) workflow.
Reproduction
- Run Shannon against a target:
./shannon start URL=<url> REPO=my-repo - Wait for completion (exploitation evidence files are written to
repos/my-repo/deliverables/) - Fix one of the reported vulnerabilities in the target app
- Run Shannon again with a new workspace:
./shannon start URL=<url> REPO=my-repo - Observe: the final report includes findings from Run 1 that the current run's vuln agent no longer flagged
Observed Impact
In a real case with two independent runs against the same target (run-zagg-app_shannon-1774435299398 on March 25, run-zagg-app_shannon-1774524842573 on March 26):
- Run 2's
injection-vulnagent produced an empty exploitation queue ({"vulnerabilities": []}) injection-exploitagent correctly never ran (not present in session.json)- However, Run 1's
injection_exploitation_evidence.mdwas still in the repo'sdeliverables/folder assembleReportActivity()concatenated it into the final report- 2 out of 9 findings in the new report were stale (INJ-VULN-PATH-TRAVERSAL, INJ-VULN-05), carried over verbatim from Run 1
Expected Behavior
A fresh (non-resume) run should only include findings from the current run. Stale deliverables from prior runs should not appear in the report.
Suggested Fix
Clear {repoPath}/deliverables/ at the start of a new workflow (but not on resume). The distinction already exists in the workflow — loadResumeState() is only called when resuming.