Skip to content

security(attestation): read sealed scientific evidence once before attestation #2302

Open

Description

@seonghobae

Finding

Fresh review of PR #2300 confirms a TOCTOU integrity defect in the unsigned scientific-validation verifier. The verifier currently hashes evidence_path via _sha256(evidence_path) and then reopens the same pathname via _load_document(evidence_path) for size/UTF-8/JSON/schema validation. A path can therefore change between the digest read and the semantic-validation read. In the hostile case, bytes A can be hashed and later attested while bytes B are the bytes actually parsed and validated.

This is not a psychometric-policy defect. It is an owner-boundary integrity defect in the future attestation foundation. The causal repair should open the validated evidence member exactly once without following symlinks, require the opened descriptor to be a bounded regular file, read bounded bytes once, and use those exact bytes for both SHA-256 and strict JSON parsing. Preserve the one-member sealed-root contract and existing schema/binding checks.

The same fresh review also found a coverage debt: _atomic_json retains a leaf-symlink guard, but the current selected 100% branch-coverage tests reach the earlier _validate_output_path symlink refusal rather than the _atomic_json guard itself. Add a direct hostile contract for that branch instead of deleting the defense.

RED / acceptance

  1. Add a deterministic hostile test that starts with invalid/malicious bytes A whose SHA-256 is the supplied evidence digest, swaps the pathname to valid bytes B only when a second path-based content read is attempted, and requires verification to reject rather than attest A after validating B.
  2. Add a direct _atomic_json symlink-output test and require no target mutation.
  3. Minimal repair: one descriptor / one bounded byte read for digest + parse; no source execution, no schema weakening, no caller-controlled trust expansion.
  4. Preserve 100% owned branch coverage and docstring coverage in the existing Scientific Validation Evidence Quality workflow.
  5. Do not claim hosted GREEN until the repaired exact-head generation is terminal.

Refs #2299 #2300 #2301 #2164 ContextualWisdomLab/TEPP#637.

Activity

  1. seonghobae commented on Sep 20, 2026

    @seonghobae
    ContributorAuthor

    Implemented ordinary-forward on canonical #2300 owner lane.

    Lineage:

    • source-level hostile RED d83e9538d9a27757243f32f4aac42a31a29e6abf;
    • selected by the exact 100% quality workflow at d5f93acf655d7d02f6b4e2ce1a47dcdade56d6ee;
    • causal repair de1e45d56e0ceb4693ebae438b60f4d4d3021c7d: open sealed leaf with O_NOFOLLOW, require regular descriptor, read one bounded byte snapshot, hash and strict-parse those same bytes;
    • refusal/coverage contract c077e31f62d1b6df9388b144b232cb1ca86b8603, including direct _atomic_json symlink-leaf coverage;
    • CHANGELOG 5d8e302b91ee0d8a44667c692f43dce272f610c7;
    • current doctoring/head 4efc51a6f82d45341b8888e53a1cc613ff63ac40.

    The RED was repaired before a terminal hosted failing generation existed, so this is source-level RED only. Do not close #2302 or claim GREEN until the exact 4efc51a6... quality/security generation is terminal and independently reviewed. This remains unsigned verifier integrity, not OIDC/Sigstore/Artifact Attestation authority.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions