Skip to content

fix(tcc): guard protected reads in scanners - #227

Draft
raysubham wants to merge 7 commits into
step-security:mainfrom
raysubham:fix/tcc-other-scanners
Draft

raysubham wants to merge 7 commits into
step-security:mainfrom
raysubham:fix/tcc-other-scanners

Conversation

@raysubham

@raysubham raysubham commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Scope

Guard direct scanner filesystem reads and symlink targets when protected-directory scanning is disabled. Preserve existing subprocess behavior. The browser-only fix is already in the baseline.

Targeted regression fixes

  • Preserve readable Node/Python global packages when another root is refused, including mixed roots within one manager.
  • Preserve readable AI CLI fallback matches beside protected fnm, mise, asdf and Volta entries through the shared glob helper.
  • Cache successful Python partial uploads using the same package body and exit status sent to the API. When a protected root becomes readable, the restored package list is uploaded instead of sending a stale unchanged reference.
  • Invalidate the affected Node global reuse marker after uploading a failed manager result, so mixed-root and all-refused recovery sends complete readable root bodies.
  • Restore command-derived CLI discovery, versions, effective npm configuration and Git tracking.
  • Keep the earlier relative-directory, cross-manager isolation and local project-discovery corrections.

Inventory contract

Protected-location omissions are expected inventory behavior. This PR adds no backend retention contract or new wire fields. Proposed API companions step-security/agent-api#10980 and step-security/agent-api#10981 were closed without merge or deployment. Existing failed-scan handling is preserved. Python's partial marker remains internal; global collection runs every scan, while delta state tracks successful uploaded bodies.

Current verification

Final signed head: b2a02fd, following dc1fcfc.

  • Independently reproduced both c1925a1 review findings on the macOS27 VM before editing. Permanent regression tests fail before and pass after the fixes.
  • Python lifecycle covers complete, successful partial, repeated partial, recovered complete, recovered unchanged, actual failure and full-sync cases. This exercises agent delta/state logic; API rejection of the old predecessor was source-traced, not a deployed failure experiment.
  • Real guarded filesystem test preserves the manifest-verified Amp binary and static version beside a protected fnm sibling, without executing the fixture binary. Other installation families share the corrected helper.
  • The same caller audit reproduced Node recovery loss with saved/reloaded state. Both mixed readable/refused roots and all-refused roots fail before and pass after the seven-line commit-path correction. API effects are source-traced; these are agent state/payload lifecycle tests.
  • Additional native-filesystem checks passed for Library fnm, mise Node, asdf and both Volta discovery depths. Fixture executables were never run.
  • Audited other glob consumers. Factory's protected-sibling control passes without a production change. Ownership/unique-version checks retain their existing error rejection.
  • Full macOS27 VM race suite, vet, formatting, unchanged module hashes after tidy, lint (0 issues), smoke (45/45), and darwin/arm64, linux/amd64, windows/amd64 builds pass.
  • Gosec retains the same 24 rule/file/detail signatures, with no new signature.
  • Populated VM community inventory on dc1fcfc matches every baseline array count, including 35 Python packages, 11 AI tools, 9 MCP configs, 147 skills and 1 IDE extension.
  • Earlier direct-read fixtures cover MCP, IDE extensions, JetBrains, Python and Node. This does not claim blanket prevention of prompts from child programs.

Integration evidence

Final b2a02fd macOS26/Linux/Windows run passed: https://github.com/step-security/integration-test/actions/runs/36868474724. Main suites passed 66/63/62 respectively, zero failed; lifecycle and data-size checks also passed.

Final b2a02fd macOS27-only run passed: https://github.com/step-security/integration-test/actions/runs/36874311803. Main suite: 62 passed, zero failed; lifecycle, applicable threat-intel and data-size checks also passed. Linux and Windows were intentionally skipped. It was dispatched sequentially to avoid workflow concurrency cancellation. All 12 product CI checks passed on the same final head. Both new commits have GitHub-verified signatures; the branch is clean and pushed.

The dc1fcfc campaign passed macOS26/Linux/Windows: https://github.com/step-security/integration-test/actions/runs/36864642270. It predates the additional Node cache correction and does not certify the final head.

Earlier a599377 runs passed without weakened assertions:

Those earlier runs do not validate the current head. PR remains draft and unmerged. No zero-regression guarantee is claimed.

Full scenario ledger: 2026-09-24-dmg-pr227-validation-runbook.md in the shared workspace docs directory.

@raysubham raysubham changed the title fix(tcc): guard protected reads in non-browser scanners fix(tcc): guard protected reads in other scanners Sep 23, 2026
@raysubham raysubham changed the title fix(tcc): guard protected reads in other scanners fix(tcc): guard protected reads in scanners Sep 23, 2026

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant