Skip to content

chore(repo): mark root package as private#163

Closed
dgilmanuni wants to merge 1 commit into
mainfrom
chore/private-dep-confusion-fix
Closed

chore(repo): mark root package as private#163
dgilmanuni wants to merge 1 commit into
mainfrom
chore/private-dep-confusion-fix

Conversation

@dgilmanuni
Copy link
Copy Markdown

Summary

Marks 1 internal package.json file(s) as "private": true to close a dependency-confusion attack class.

Background

Cantina finding #677 identified two internal package names in interface (datadog-cloud-universe, datadog-dashboards-universe) that were unscoped and not marked "private": true, creating dependency-confusion exposure: if any tooling ever fell back from workspace resolution to the public npm registry for these names, an attacker who registered the name first would achieve arbitrary code execution in the install context (developer laptops or CI runners).

A sweep across the rest of the Uniswap orgs' local-checkout repos found the same vulnerability shape in 1 package.json file(s) here, plus dozens more across backend, unichain, and others (separate PRs). Several internal Uniswap package names across the org are already registered to third-party accounts on public npm — including ai-agents, cloudflare, data-api, mission-control, notification-service, liquidity, and websockets — meaning the dependency-confusion target is currently live, not theoretical.

What changed

  • package.json (the-compact)

The fix is purely defensive: npm / bun refuse to publish a package marked private, and the resolver's behavior is unchanged for any consumer that already uses workspace or lockfile resolution. No behavior change is expected for builds, tests, deploys, or developer workflows.

Test plan

  • All edited files still parse as valid JSON (verified locally)
  • "private": true set on each
  • CI passes with no lockfile or workspace-config churn

Session context

  • Why this scope: Per your direction, opening one PR per repo with Uniswap/security tagged so the security team can sign off on the closing of the class without surprise.
  • What was deliberately skipped: apps/mobile/src/{"name":"src"} Metro module-resolution markers (not a dep-confusion vector — bundlers don't resolve src from npm), and cypress-hardhat (intentionally published under uniswap-labs-service-account).
  • Deeper convention fix: The backend cookiecutter template at scripts/ecsServiceTemplate/T_SERVICE_NAME/infra/package.json is included in the backend PR so future generated services start private-by-default. Universe's Nx generator already does the right thing.
  • Out of scope here: A CI lint that fails on any new unscoped + non-private package.json would prevent regression entirely; tracked separately.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@dgilmanuni
Copy link
Copy Markdown
Author

Closing after deeper analysis.

"private": true is a signaling/intent fix, not a vulnerability fix. The private flag only blocks npm publish; it does NOT change how dependencies get resolved. So adding it to these package.json files does not actually prevent dependency confusion — an attacker who squats the unscoped name on npm still wins if any future change creates a registry-resolution path.

The class-closing fix is renaming to a controlled scope (@uniswap/<name>), which requires coordinated lockfile regeneration, consumer dep updates, and (for Pulumi packages) state migration. That work needs proper planning and will be scoped as a separate effort.

Reopening if we decide the cosmetic signaling value alone justifies the reviewer attention.

@dgilmanuni dgilmanuni closed this Apr 24, 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.

2 participants