Labels: bug, forensics-module
Severity: S1.
| Finding (path:line) |
Issue |
modules/forensics/reporting/writeup_builder.py:373-380 |
_load_artefacts_by_family reads getattr(r,"family"/"type"/"data") but the fields are artifact_family/artifact_type/data_json -> every row falls into "unknown" with empty payload; every writeup is generated against zero artifacts (blank Ghidra/memory/network sections) |
modules/forensics/api_router.py:1080-1116 |
delete_project deletes 6 child tables but NOT FindingSuppressionRecord, AnalystDirectiveRecord, SolidEvidenceRecord, AnswerCandidateRecord (all reference project_id) -> FK violation crash or orphaned rows corrupting future fingerprint matches |
modules/forensics/services/machine_readiness.py via api_router.py:1230-1250 |
check_readiness auto-enqueues run_forensics_analysis with no check for an already-queued/running task -> a double-click runs two full pipelines on the same target, racing on artifact inserts |
modules/forensics/api_router.py:1356,1395,1900 |
list_investigations/list_findings/list_evidence return unbounded sets (no page/page_size) -> multi-MB responses, OOM under load |
modules/forensics/db_models/investigation.py |
InvestigationRunRecord/AgentStepRecord/WriteUpRecord/AnswerCandidateRecord have no team_id; isolation relies solely on the project join -> any query omitting the join leaks cross-tenant |
modules/forensics/workflow/states/freeflow.py:61-160 |
_HARD_TURN_CAP=50 turns on Opus with no per-investigation cost ceiling / kill-switch and no max_cost_usd config -> runaway spend with no metric until billed |
Acceptance: writeup builder reads the real field names (add a test asserting non-empty artifact families); delete_project covers every project_id child (or FK ON DELETE CASCADE); readiness enqueue is idempotent; list endpoints paginate in SQL; child tables carry team_id or a documented join contract; freeflow honors a cost ceiling.
Labels: bug, forensics-module
Severity: S1.
modules/forensics/reporting/writeup_builder.py:373-380_load_artefacts_by_familyreadsgetattr(r,"family"/"type"/"data")but the fields areartifact_family/artifact_type/data_json-> every row falls into"unknown"with empty payload; every writeup is generated against zero artifacts (blank Ghidra/memory/network sections)modules/forensics/api_router.py:1080-1116delete_projectdeletes 6 child tables but NOTFindingSuppressionRecord,AnalystDirectiveRecord,SolidEvidenceRecord,AnswerCandidateRecord(all reference project_id) -> FK violation crash or orphaned rows corrupting future fingerprint matchesmodules/forensics/services/machine_readiness.pyviaapi_router.py:1230-1250check_readinessauto-enqueuesrun_forensics_analysiswith no check for an already-queued/running task -> a double-click runs two full pipelines on the same target, racing on artifact insertsmodules/forensics/api_router.py:1356,1395,1900list_investigations/list_findings/list_evidencereturn unbounded sets (no page/page_size) -> multi-MB responses, OOM under loadmodules/forensics/db_models/investigation.pyInvestigationRunRecord/AgentStepRecord/WriteUpRecord/AnswerCandidateRecordhave noteam_id; isolation relies solely on the project join -> any query omitting the join leaks cross-tenantmodules/forensics/workflow/states/freeflow.py:61-160_HARD_TURN_CAP=50turns on Opus with no per-investigation cost ceiling / kill-switch and nomax_cost_usdconfig -> runaway spend with no metric until billedAcceptance: writeup builder reads the real field names (add a test asserting non-empty artifact families); delete_project covers every project_id child (or FK ON DELETE CASCADE); readiness enqueue is idempotent; list endpoints paginate in SQL; child tables carry team_id or a documented join contract; freeflow honors a cost ceiling.