Skip to content

security(linker): reject unsafe package aliases#800

Merged
jdx merged 2 commits into
mainfrom
security/validate-package-link-names
May 28, 2026
Merged

security(linker): reject unsafe package aliases#800
jdx merged 2 commits into
mainfrom
security/validate-package-link-names

Conversation

@jdx

@jdx jdx commented May 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • reject package/dependency aliases that are not npm node_modules slots before linking
  • cover isolated and hoisted linker paths
  • register ERR_AUBE_UNSAFE_PACKAGE_NAME for reporters/CI

Tests

  • PATH="$HOME/.cargo/bin:$PATH" cargo fmt --check
  • PATH="$HOME/.cargo/bin:$PATH" cargo test -p aube-linker validate_package_link_name
  • PATH="$HOME/.cargo/bin:$PATH" cargo test -p aube-codes

This PR was generated by Codex.


Note

Medium Risk
Security-hardening on install/link paths can fail installs if lockfiles contain unusual dependency keys that previously linked; behavior is intentional fail-closed.

Overview
Adds defense-in-depth so only valid npm node_modules slot names (name or @scope/name) are used when building paths under node_modules.

A new validate_package_link_name helper rejects path-like aliases (.., extra slashes, absolute paths, Windows drive prefixes, null bytes, etc.). It runs during materialize (package name and dependency keys), isolated top-level and workspace symlinks, and hoisted placement planning. Hoisted planning and HoistedPlacements::from_graph now return Result so unsafe names fail install/rebuild instead of silently planning bad paths.

Registers ERR_AUBE_UNSAFE_PACKAGE_NAME (exit code 92) in aube-codes, linker diagnostics, and docs/error-codes.data.json, alongside unit tests for accepted and rejected names.

Reviewed by Cursor Bugbot for commit 9072c5c. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds defense-in-depth validation that rejects unsafe package/dependency aliases before they can be used to build paths under node_modules, preventing path-traversal attacks from malicious or malformed lockfile entries. A new validate_package_link_name helper rejects names that are not valid npm slots (name or @scope/name), and failures surface as the new ERR_AUBE_UNSAFE_PACKAGE_NAME error (exit 92).

  • validate_package_link_name and is_safe_package_component in materialize.rs block empty strings, NUL bytes, backslashes, leading slashes, Windows drive prefixes, and any multi-segment shape that isn't a scoped npm name.
  • Validation is wired into all three link paths (isolated materialize_into, hoisted place/plan_importer/from_graph, and the three direct-link loops in link.rs), with from_graph and plan_importer signatures updated to propagate Result.
  • ERR_AUBE_UNSAFE_PACKAGE_NAME is registered in aube-codes and docs/error-codes.data.json; unit tests cover accepted npm names and a representative set of rejected path shapes.

Confidence Score: 5/5

Safe to merge. All three linker paths validate names before constructing filesystem paths, error propagation is correctly threaded through the call chain, and the only caller of the updated from_graph signature is updated.

The validation logic correctly blocks all practical path-traversal shapes. The Result-propagation refactor is complete — every call-site that previously returned Self or a plain value now propagates errors, and the single external caller in rebuild.rs is updated. No gaps in coverage were found across isolated, hoisted, or workspace linker paths.

No files require special attention.

Important Files Changed

Filename Overview
crates/aube-linker/src/materialize.rs Adds validate_package_link_name and is_safe_package_component helpers; validation runs at the top of materialize_into for both the package name and its dependency keys before any path is built.
crates/aube-linker/src/hoisted.rs Threads Result through place, plan_importer, and from_graph; validate_package_link_name is called at the top of place so every dep name (direct and transitive) is checked before being inserted into the plan.
crates/aube-linker/src/link.rs Adds three validate_package_link_name call-sites before nm.join(&dep.name) in the isolated top-level, workspace-symlink, and workspace-dep loops, covering the isolated linker path.
crates/aube-linker/src/error.rs Adds UnsafePackageName(String) variant with the correct ERR_AUBE_UNSAFE_PACKAGE_NAME diagnostic code.
crates/aube-codes/src/errors.rs Registers ERR_AUBE_UNSAFE_PACKAGE_NAME constant and adds a CodeMeta entry (exit code 92, MISC_SAFETY category) positioned after the shebang entry in the ALL array.
crates/aube/src/commands/rebuild.rs Updates the single HoistedPlacements::from_graph call-site to propagate the now-Result return with ?.
docs/error-codes.data.json Adds the ERR_AUBE_UNSAFE_PACKAGE_NAME entry (exit code 92) to the JSON data file, kept in sync with the Rust source.
crates/aube-linker/src/lib.rs Re-exports validate_package_link_name as pub(crate) so it can be called from link.rs and hoisted.rs without importing from materialize directly.

Reviews (2): Last reviewed commit: "fix(linker): surface unsafe hoisted name..." | Re-trigger Greptile

Comment thread crates/aube-linker/src/materialize.rs Outdated
Comment thread crates/aube-linker/src/hoisted.rs Outdated
Comment thread crates/aube-codes/src/errors.rs Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f3e22aa. Configure here.

Comment thread crates/aube-linker/src/hoisted.rs Outdated

jdx commented May 28, 2026

Copy link
Copy Markdown
Owner Author

Addressed the review feedback in 9072c5c:

  • removed the redundant leading-backslash check from package-link validation
  • made hoisted placement recomputation propagate unsafe package names instead of silently skipping an importer
  • reordered ERR_AUBE_UNSAFE_PACKAGE_NAME after the shebang safety code and regenerated docs/error-codes.data.json

Local checks run:

  • cargo fmt --check
  • cargo test -p aube-linker validate_package_link_name
  • cargo test -p aube-codes
  • cargo check -p aube

This comment was generated by Codex.

@jdx jdx merged commit 633a973 into main May 28, 2026
18 checks passed
@jdx jdx deleted the security/validate-package-link-names branch May 28, 2026 06:21
@greptile-apps greptile-apps Bot mentioned this pull request May 28, 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