# Tampering with arbitrary packages in @types scope of npm

dt-mergebot only checked first 100 (later 3000) PR files, letting an attacker hide malicious edits to other @types packages and merge them.

- Payout: Research
- Severity: high
- Program: DefinitelyTyped
- Write-up by: RyotaK
- Disclosed: 2021-08-08
- Write-up quality: 8/10
- Original: https://blog.ryotak.net/post/definitelytyped-tamper-with-arbitrary-packages-en/
- Library page: https://bugbountylibrary.com/r/blog%3Ablog-ryotak-net-post-definitelytyped-tamper-with-arbitrary-packages-en
- Tags: area:oss domain:oss impact:integrity kind:research platform:research sev:high tech:github-actions tech:nodejs technique:incomplete-fix technique:regression technique:source-review vuln:access-control vuln:business-logic

**Target:** GitHub PR review bot (dt-mergebot) and types-publisher for @types npm packages
**Root cause:** dt-mergebot fetched only the first page of PR files (first:100, later capped at 3000 by GitHub API) and only console.warn'd on truncation instead of aborting, so files beyond the limit escaped package-maintainer permission checks.
**Steps:**
1. Add a type definition for an untyped npm library via PR and set yourself as maintainer; get it merged
2. Open a new PR adding 100 files to that package's directory plus edits to a target file in another @types package
3. dt-mergebot's GraphQL `files(first: 100)` returns only 100 nodes; totalCount>nodes triggers only console.warn
4. Bot grants you merge permission based on the visible package; comment `Ready to merge`
5. PR merges, tampering with the hidden target file
6. Regression: after pagination fix, send PR modifying 3001+ files; GitHub API caps files/totalCount at 3000, bypassing checks again
**How found:** Recalled prior Homebrew PR-parsing vulnerability, read dt-mergebot source, noticed `files(first: 100)` with only a console.warn on totalCount mismatch, hypothesized >100-file PRs skip permission checks; later re-read code post-fix and spotted GitHub's 3000-file API cap as a regression.
**Exploitation:** Attacker gains package-maintainer status legitimately by adding a new type definition, then crafts a PR where the permission-checked files are benign but the >100th (or >3000th) file modifies another @types package; bot approves merge and the malicious change lands in DefinitelyTyped, propagating to npm @types packages.
**Escalation:** Chained legitimate maintainer onboarding with API pagination limits; regression showed the fix was bypassable via GitHub's 3000-file cap, and a separate symlink flaw in types-publisher allowed publishing unintended files.
**Insight:** When a bot derives authorization from a paginated API listing, check whether truncation is fatal or merely logged, and whether the upstream API itself caps results (GitHub 3000 files) so pagination can't save you; also test symlink handling in publish/copy steps.
