Skip to content

Harden adapter doctor: read manifest files[].path entries via resolveWithinProject (symlink containment) #489

@toshtag

Description

@toshtag

Context

Follow-up from the security hardening PR #488 (Codex review of bd84281). The follow-up review noted a remaining same-smell path: adapter doctor reads each manifest files[].path entry's on-disk content with a lexical join(cwd, entry.path) rather than through resolveWithinProject.

The manifest schema (RelativePosixPath) already rejects .. / absolute / drive-letter paths, so an entry cannot lexically point outside the project. But a manifest entry pointing at a path whose final component (or an ancestor) is a symlink to an outside file would still be followed on read — the same symlink-escape class the PR closed for readManifest/writeManifest and the context-pack reads.

Why this is a follow-up, not a blocker

adapter doctor does not echo file contents into its output (it hashes them and reports drift codes), so this is an information-* exposure-resistant* read, not a direct leak. Severity is lower than the PR's High findings. The PR deliberately scoped to the manifest file I/O + the install/upgrade trust paths to avoid widening the change.

Goal

Route doctor's per-entry manifest file reads (and any other join(cwd, manifestEntry.path) reads in the adapter command surface — e.g. adapter conformance, adapter doctor's listOwnedCandidates/detectContractDrift reads) through resolveWithinProject (or the same readWithinProject degrade helper used in src/core/pack/loaders.ts), so a symlinked manifest-tracked path is refused rather than followed.

Constraints

  • Doctor must stay non-throwing / tolerant — a refused entry should become a diagnostic (e.g. an ADAPTER_FILE_* issue or a dedicated containment issue), not an exit-3 throw.
  • No behavior change for legitimate in-project files.

Acceptance

  • A manifest entry whose path is a symlink to an outside file is NOT read through; doctor reports it as a diagnostic instead.
  • Regression test with a symlinked manifest-tracked file.
  • Same treatment audited for adapter conformance.

Refs: PR #488, related ownership follow-up #487.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions