Skip to content

fix(contract): constrain canonical code-evidence paths - #542

Open
sylvesterkaczmarek wants to merge 2 commits into
openai:mainfrom
sylvesterkaczmarek:fix/code-evidence-safe-paths
Open

fix(contract): constrain canonical code-evidence paths#542
sylvesterkaczmarek wants to merge 2 commits into
openai:mainfrom
sylvesterkaczmarek:fix/code-evidence-safe-paths

Conversation

@sylvesterkaczmarek

Copy link
Copy Markdown

Summary

Require canonical codeEvidence[].path values to stay inside the same repository-relative POSIX path boundary used elsewhere in the scan contract.

Fixes #541.

Reproduction / evidence

Current upstream main at 37bf87a692fc72d41f7312cc48808d699d204fba explicitly validates every ordinary finding location with the canonical safe-path helper, but the findings schema defines codeEvidence[].path as only a nonempty string.

A sealed-contract reproduction is:

  1. copy the bundled completed-scan example;
  2. add otherwise valid code evidence whose path is ../../outside.ts;
  3. recompute the sealed findings.json digest in scan-manifest.json;
  4. call loadContract().

On the unfixed schema, the traversal path satisfies the code-evidence schema and no separate canonical code-evidence path check rejects it.

The regression in this PR exercises the real sealed loader with these invalid shapes:

  • ../../outside.ts;
  • /etc/passwd;
  • C:/outside.ts;
  • src\\outside.ts;
  • .;
  • src:stream.ts;
  • a path containing NUL.

It also reseals and loads a valid src/extract.py control.

Root cause

Location path safety was implemented in explicit validator code, while optional code evidence was added with only a schema-level nonempty-string requirement. The shared findings schema is consumed by both TypeScript validation and the Python finalizer, so the missing constraint crossed both validation surfaces.

Fix

Add a safe repository-relative path pattern to codeEvidence[].path. It rejects absolute paths, traversal segments, backslashes, colon-bearing paths, the standalone dot path, and NUL characters.

The schema remains otherwise unchanged.

Tests / validation

Added code-evidence-paths.test.ts, which mutates the real completed-scan fixture, recomputes the findings artifact digest, and calls loadContract() for every invalid path plus a valid control.

The branch is based directly on current upstream main at 37bf87a692fc72d41f7312cc48808d699d204fba and is not behind it. Production change: 2 additions and 1 deletion in the shared findings schema. The remainder is focused regression coverage.

Full repository tests cannot be run in this execution environment because the repository cannot be cloned here. Pushed-head CI remains the authoritative full-suite validation.

Risk

Low. This only rejects code-evidence paths that violate the repository-relative path model already enforced for canonical finding locations. Valid repository-relative paths are unchanged.

@github-actions github-actions Bot added the bug Something isn't working label Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Canonical code-evidence paths bypass repository-relative path validation

1 participant