T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/check_task.py:61
- Finding
- Completion Gate Accepts Forged or Incomplete Verification Artifacts<![CDATA[ ## Vulnerability Details **File Location**: `scripts/check_task.py:61-79` **Vulnerability Type**: Insufficient validation of security-critical proof artifacts **Risk Level**: Medium ### Vulnerable Code ```python if verdict: if verdict.get("overall") != PASS: failures.append(f"overall is {verdict.get('overall')!r}, expected PASS") criteria = verdict.get("criteria") if not isinstance(criteria, list) or not criteria: failures.append("criteria must be a non-empty list") else: for index, criterion in enumerate(criteria, start=1): if not isinstance(criterion, dict): failures.append(f"criterion #{index} must be an object") continue cid = criterion.get("id", f"#{index}") status = criterion.get("status") if status not in VALID_STATUSES: failures.append(f"{cid} has invalid status {status!r}") elif status != PASS: failures.append(f"{cid} is {status}, expected PASS") if not problems_are_clear(problems_path): failures.append("problems.md is not empty") ``` ### Technical Analysis The completion gate treats the repository-controlled `verdict.json` file as authoritative without establishing that it represents the acceptance criteria frozen in `spec.md`. The implementation only requires: 1. `spec.md` to exist. 2. `verdict.json` to contain `overall: "PASS"`. 3. `criteria` to be a non-empty list whose supplied entries have `status: "PASS"`. 4. `problems.md` to be absent or empty. It does not: - Extract acceptance-criterion identifiers from `spec.md`. - Require an exact one-to-one match between the frozen criteria and verdict entries. - Reject duplicate, omitted, or unexpected criterion identifiers. - Require the verdict to satisfy the bundled verdict schema. - Require `phase` to identify an independent verification phase. - Require evidence for each acceptance criterion. - Authenticate the veri ...[truncated 1608 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the canonical acceptance-criterion identifiers from `spec.md` using a strict, documented format. 2. Require the verdict to contain exactly one result for every criterion in the frozen specification. 3. Reject missing, duplicate, malformed, and unexpected criterion identifiers. 4. Apply full JSON Schema validation before evaluating completion. 5. Require completion verdicts to have an explicit verification phase, such as `phase: "verify"`. 6. Require structured evidence references for every PASS result and verify that referenced artifacts exist. 7. Bind `task_id` in the verdict to the task directory and specification. 8. If verifier separation must be technically enforceable, use provenance that the builder cannot freely forge, such as separately controlled CI identity, signed attestations, or repository permissions. A plain editable `agent` field is not sufficient. 9. Add regression tests proving that the gate rejects: - Omitted criteria. - Duplicate criteria. - Criteria absent from the specification. - Minimal fabricated verdicts. - Non-verification phases. - Missing evidence. ]]>
