Skip to content

fix(aztec-up): Do not leak node_modules/.bin into the PATH#22709

Merged
vezenovm merged 6 commits into
merge-train/fairiesfrom
mv/aztec-up-bin-leak
Apr 22, 2026
Merged

fix(aztec-up): Do not leak node_modules/.bin into the PATH#22709
vezenovm merged 6 commits into
merge-train/fairiesfrom
mv/aztec-up-bin-leak

Conversation

@vezenovm
Copy link
Copy Markdown
Contributor

@vezenovm vezenovm commented Apr 21, 2026

Summary

The aztec-up installer adds $HOME/.aztec/current/node_modules/.bin to the user's shell PATH. That directory contains the bin entries of every transitive npm dependency of the Aztec packages, so ~40 third-party bins (jest, tsc, tsserver, semver, uuid, json5, pino, mime, rlp, ...) end up on PATH, silently shadowing user-installed versions.

This PR exposes only the 7 intended @aztec/*-owned bins and drops node_modules/.bin from the PATH line.

Why

Two problems with the current setup:

  1. DX / correctness. A developer with jest@29 pinned locally silently runs Aztec's bundled jest@30 when typing jest, producing confusing errors (e.g. the renamed --testPathPattern flag). Same trap for tsc, semver, etc. The user has no way to enumerate what's been shadowed without reading the dep tree.
  2. Invocation surface. Install-time trust is unchanged — every package in the graph already runs code via postinstall or when Aztec uses it — but putting transitive bins on PATH adds a new invocation vector: a compromised transitive bin can fire on normal dev activity (jest, tsc) rather than only when Aztec calls it. Notably, that bypasses --ignore-scripts-style defenses and is stealthier than a postinstall payload. Standard package managers (npm install -g, pipx, brew, cargo install) do not expose transitive bins on PATH; they symlink only the package's declared entry points.

Context: https://gist.github.com/AztecBot/fc2f40d50592c468429f922921a271f2 and https://www.notion.so/aztecnetwork/Getting-Started-Token-Tutorial-Walk-Through-348a1f6b0e35806a884edc16742866b9

Changes

  • aztec-up/bin/0.0.1/install — new symlink_aztec_bins function, called after install_aztec_packages. Iterates node_modules/.bin/*, keeps only symlinks whose target starts with ../@aztec/, and re-links them into $version_path/bin/ using relative paths (../node_modules/.bin/<name>). No hard-coded list: the set of exposed bins follows whatever @aztec/* packages declare.
  • aztec-up/bin/0.0.1/aztec-install — drops $HOME/.aztec/current/node_modules/.bin from the shell-profile PATH export.
  • aztec-up/bin/0.0.1/aztec-up — drops node_modules/.bin from aztec-up env output so per-project .aztecrc switching also skips the leak.

Each version's bin/ stays self-contained, so aztec-up use <ver> flips the entire bin set atomically via the current symlink — same mechanism as today.

Verification

Ran the new symlink_aztec_bins function against an existing ~/.aztec/current install, mirrored into a throwaway AZTEC_HOME:

=== Bins exposed in version bin/ ===
aztec aztec-wallet bb bb-cli blob-client noir-codegen txe

=== Symlink resolution ===
aztec         -> .../node_modules/@aztec/aztec/scripts/aztec.sh
aztec-wallet  -> .../node_modules/@aztec/cli-wallet/dest/bin/index.js
bb            -> .../node_modules/@aztec/bb.js/dest/node/bin/index.js
bb-cli        -> .../node_modules/@aztec/bb-prover/dest/bb/index.js
blob-client   -> .../node_modules/@aztec/blob-client/dest/client/bin/index.js
noir-codegen  -> .../node_modules/@aztec/noir-noir_codegen/lib/main.js
txe           -> .../node_modules/@aztec/txe/dest/bin/index.js

=== Transitive bins absent from version bin/ ===
jest tsc tsserver semver uuid json5 pino pino-pretty mime rlp  (all absent)

=== Exec through the chain ===
PATH=$THROWAWAY_BIN:... aztec-wallet --help  →  prints help OK

7 bins exposed vs. 40 before; all resolve; end-to-end execution works.

Confirmed non-regressions

Audited Aztec production CLI code for bare-name shell-outs that could rely on transitive bins being on PATH:

  • yarn-project/aztec/scripts/aztec.sh — shells out to anvil, nargo, nc, and itself. anvil/nargo live in current/bin/ (installed by aztec-install), nc is system. Unaffected.
  • yarn-project/aztec/src/cli/cmds/compile.ts / profile_gates.ts — resolve bb via findBbBinary() (absolute path from @aztec/bb.js), fall back to bare 'bb' which remains reachable as a new symlink in current/bin/.
  • yarn-project/cli/src/cmds/misc/update/npm.ts — intentionally invokes user's system npm/pnpm/yarn. Unaffected.

No other bare-name invocations of transitive bins.

Migration

Fresh installs and aztec-up install <ver> pick up the fix automatically. Existing users still have the old export PATH=…:current/node_modules/.bin:… line in their shell profile; that gets rewritten the next time they run aztec-install (the existing dedup at aztec-install:210 strips old entries). Worth flagging in release notes.

@vezenovm vezenovm requested a review from charlielye as a code owner April 21, 2026 20:34
@vezenovm vezenovm changed the title fix: do not leak node_modules/.bin into the PATH fix(aztec-up): do not leak node_modules/.bin into the PATH Apr 21, 2026
@vezenovm vezenovm changed the title fix(aztec-up): do not leak node_modules/.bin into the PATH fix(aztec-up): Do not leak node_modules/.bin into the PATH Apr 21, 2026
@vezenovm vezenovm requested a review from nchamo April 22, 2026 14:43
Copy link
Copy Markdown
Contributor

@nchamo nchamo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great finding and fix!

Bash is not my specialty, but looks pretty good. I left a few comments we can discuss if needed

Comment thread docs/docs-developers/docs/resources/migration_notes.md Outdated
Comment thread aztec-up/bin/0.0.1/aztec-install Outdated
Comment thread aztec-up/bin/0.0.1/install
Comment thread aztec-up/bin/0.0.1/install Outdated
Comment thread aztec-up/bin/0.0.1/install
Copy link
Copy Markdown
Contributor

@nchamo nchamo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@vezenovm vezenovm merged commit 3d7d895 into merge-train/fairies Apr 22, 2026
12 checks passed
@vezenovm vezenovm deleted the mv/aztec-up-bin-leak branch April 22, 2026 20:03
@AztecBot
Copy link
Copy Markdown
Collaborator

❌ Failed to cherry-pick to v4-next due to conflicts. (🤖) View backport run.

vezenovm added a commit that referenced this pull request Apr 23, 2026
…22709) (#22740)

Backport of #22709
to `v4-next`.

## Conflict resolution

The automatic cherry-pick failed with a conflict in
`docs/docs-developers/docs/resources/migration_notes.md`. The PR adds a
new `### [CLI] aztec-up no longer exposes transitive npm bins on PATH`
entry to the `## TBD` section. In `next` that section already contained
a `### [Protocol] Domain separators introduced…` entry (from an
unrelated change); in `v4-next` the `## TBD` section is empty, so 3-way
merge couldn't place the new entry.

Resolution: kept only the new `[CLI]` section from #22709, dropped the
unrelated `[Protocol] Domain separators` context that isn't part of
#22709 and doesn't apply to `v4-next`.

Final diff stat matches #22709 exactly: `+56 / -5`, 4 files
(`aztec-up/bin/0.0.1/aztec-install`, `aztec-up/bin/0.0.1/aztec-up`,
`aztec-up/bin/0.0.1/install`,
`docs/docs-developers/docs/resources/migration_notes.md`).

## Commits

1. `cherry-pick: ... (with conflicts)` — raw cherry-pick with conflict
markers committed as-is.
2. `fix: resolve cherry-pick conflicts` — removes markers and the
unrelated `[Protocol]` section.

No build-fixes commit needed — only shell scripts and a Markdown doc
touched, no compilation affected.

## Original PR summary

The `aztec-up` installer was adding
`$HOME/.aztec/current/node_modules/.bin` to the shell `PATH`, exposing
~40 transitive npm bins (`jest`, `tsc`, `tsserver`, `semver`, `uuid`,
`json5`, `pino`, `mime`, `rlp`, ...) and silently shadowing
user-installed versions. This PR exposes only the 7 `@aztec/*`-owned
bins via a new `symlink_aztec_bins` function and drops
`node_modules/.bin` from the `PATH` line and `aztec-up env` output.

Backport triggered by `backport-to-v4-next` label on #22709. Original
auto-backport run:
https://github.com/AztecProtocol/aztec-packages/actions/runs/24837667070

ClaudeBox log: https://claudebox.work/s/c3ea95f8c16a721b?run=1
chrismarino pushed a commit to chrismarino/aztec-packages that referenced this pull request May 5, 2026
BEGIN_COMMIT_OVERRIDE
fix(aztec test): anchor contract log filter to avoid framework spam
(AztecProtocol#22726)
fix(aztec-up): Do not leak node_modules/.bin into the PATH (AztecProtocol#22709)
END_COMMIT_OVERRIDE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants