openai / openai/codex-security

TypeScript contract loader accepts reversed finding line ranges

Open
#560 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
10.8k
Forks
801
Avg merge
1d 8h
Merged PRs (30d)
257

Description

Summary

The canonical TypeScript contract loader accepts a finding location whose endLine is less than its startLine, even though the bundled Python producer rejects that same location before sealing.

This creates a producer/consumer validation mismatch: an externally constructed, correctly resealed completed-scan bundle can load through loadContract() with a line range that Codex Security itself would never finalize.

Reproduction / evidence

Current upstream main at 37bf87a692fc72d41f7312cc48808d699d204fba validates ordinary finding locations in two different ways.

The Python finalizer uses _validate_location() and requires:

end = location.get("endLine", start)
...
if not isinstance(end, int) or end < start:
    raise ContractError(...)

The shared JSON schema only constrains startLine and endLine independently to positive integers. The TypeScript validateCanonicalContract() then validates each location path but does not compare the two line numbers.

A deterministic sealed-contract reproduction is:

  1. copy the bundled examples/completed-scan fixture;
  2. change the first finding location to startLine: 41, endLine: 40;
  3. recompute the sealed findings.json SHA-256 in scan-manifest.json;
  4. call loadContract().

Current behavior: the bundle loads successfully.

Expected behavior: the SDK loader rejects the same reversed line range the producer rejects.

Root cause

The relational endLine >= startLine invariant lives in Python finalization but was not mirrored in the TypeScript canonical-validation pass. JSON Schema Draft 2020-12 does not express this sibling-value comparison in the existing schema without a nonstandard extension.

Suggested fix

During validateCanonicalContract(), reject any ordinary finding location whose defined endLine is less than startLine.

Add a focused regression that mutates and reseals the real bundled completed-scan fixture, verifies the reversed range is rejected, and retains a valid multi-line range control.

Impact

This is contract-integrity correctness. Invalid ranges can reach SDK consumers and downstream source-link/reporting logic even though the canonical producer rejects them, so producer and consumer disagree about what constitutes a valid sealed finding.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with validateCanonicalContract() and loadContract(), then inspect the bundled examples/completed-scan fixture and the existing canonical-validation tests. Reseal a copy with a reversed finding range and verify loading rejects it, while retaining a valid multi-line range control.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.