Skip to content

Harden scanner trust boundaries: non-suppressible permit-all banner + reject in-node_modules PnP runtime#188

Merged
LadyBluenotes merged 3 commits into
mainfrom
m2/pr0-hardening
Jul 2, 2026
Merged

Harden scanner trust boundaries: non-suppressible permit-all banner + reject in-node_modules PnP runtime#188
LadyBluenotes merged 3 commits into
mainfrom
m2/pr0-hardening

Conversation

@LadyBluenotes

@LadyBluenotes LadyBluenotes commented Jul 2, 2026

Copy link
Copy Markdown
Member

Summary

Two low-risk, self-contained hardening changes to the discovery/notice surfaces. No behavior change for real projects today; both close latent gaps before later trust-lockfile work builds on them.

1. Refuse a Yarn PnP runtime resolved from within node_modules

The scanner reads package data as files and never executes discovered package code — with one sanctioned exception: loading the project's own Yarn PnP runtime (.pnp.cjs) to map package identities to readable locations. That is safe only for the project's root-or-ancestor manifest.

Today findPnpFile walks upward-only, so a .pnp.cjs shipped inside a dependency is unreachable — there is no live bug. But nothing asserts that: a future change that started the search from a package directory could require() a package-supplied .pnp.cjs and execute untrusted code in-process.

This adds an explicit, fail-closed guard: if the resolved PnP runtime lives within node_modules, loadPnpApi throws a clear diagnostic instead of loading it. Exposed as a pure isPnpRuntimeWithinNodeModules predicate for direct testing.

2. Regression test for the non-suppressible permit-all banner

The intent.skills: ["*"] permit-all risk banner must stay visible even under --no-notices / INTENT_NO_NOTICES (a risk acknowledgment a CI run can mute is not a safeguard). The fix already shipped; this locks it with a test asserting the banner prints through the notices channel under suppression, other notices stay suppressed, and it never leaks into the warnings channel.

Impact / compatibility

  • No observable change for legitimate Yarn PnP projects (their .pnp.cjs lives at the project/workspace root, not in node_modules).
  • The only newly-rejected case is a PnP runtime resolved from inside node_modules — precisely the untrusted case, and one the current upward-only search doesn't produce.
  • Existing scanner tests (54) unchanged and green.

Summary by CodeRabbit

  • Bug Fixes

    • Improved runtime safety by blocking Yarn Plug’n’Play configurations loaded from within node_modules.
    • The app now trusts only project-root or ancestor PnP runtime files, reducing the risk of loading an unintended environment.
  • Tests

    • Added coverage for the new PnP trust-boundary behavior.
    • Expanded CLI output checks to ensure notices and banners appear in the correct output stream.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c55f2012-2187-4bfd-b77a-34080329a092

📥 Commits

Reviewing files that changed from the base of the PR and between 8a25a7b and a2b66d4.

📒 Files selected for processing (4)
  • .changeset/fruity-ghosts-brake.md
  • packages/intent/src/discovery/scanner.ts
  • packages/intent/tests/cli-output.test.ts
  • packages/intent/tests/pnp-trust-boundary.test.ts

📝 Walkthrough

Walkthrough

Adds a guard so the PnP loader refuses runtimes resolved from within node_modules, trusting only project-root/ancestor .pnp.cjs files, via a new exported helper function. Includes a changeset entry and new test suites for the trust boundary and for printNotices CLI banner output.

Changes

PnP Trust Boundary Enforcement

Layer / File(s) Summary
PnP runtime path guard
packages/intent/src/discovery/scanner.ts, .changeset/fruity-ghosts-brake.md
Adds isPnpRuntimeWithinNodeModules helper and uses it in loadPnpApi to throw when the discovered PnP runtime is resolved within node_modules; documents the patch in a changeset.
Trust boundary tests
packages/intent/tests/pnp-trust-boundary.test.ts
Tests isPnpRuntimeWithinNodeModules against project-root, ancestor, node_modules (including nested), and substring-only path cases.

CLI Notice Output Tests

Layer / File(s) Summary
printNotices banner coverage
packages/intent/tests/cli-output.test.ts
Adds tests confirming ALLOW_ALL_NOTICE prints regardless of suppression settings, other notices respect suppression, and the banner routes to stderr not stdout.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: KevinVandy, schiller-manuel

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes both hardening changes: the PnP trust-boundary guard and the non-suppressible permit-all banner test.
Description check ✅ Passed The description covers the changes and impact well, but it does not follow the template's checklist and release-impact sections exactly.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch m2/pr0-hardening

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Jul 2, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit a2b66d4

Command Status Duration Result
nx run-many --targets=build --exclude=examples/** ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2026-07-02 02:47:47 UTC

@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/TanStack/intent/@tanstack/intent@188

commit: a2b66d4

@LadyBluenotes LadyBluenotes merged commit 2a25b36 into main Jul 2, 2026
9 checks passed
@LadyBluenotes LadyBluenotes deleted the m2/pr0-hardening branch July 2, 2026 02:54
@github-actions github-actions Bot mentioned this pull request Jul 2, 2026
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