Repository navigation
Description
Summary
google-gax declares rimraf under dependencies, but rimraf does not appear
to be used by any shipped runtime code. Because rimraf@5 transitively depends
on glob@10 → minimatch@9 → brace-expansion@2, every consumer of google-gax
currently inherits GHSA-mh99-v99m-4gvg (brace-expansion, DoS via
unbounded expansion) in their production dependency tree.
If the declaration is indeed build-only or vestigial, moving it to
devDependencies (or removing it) would clear the advisory for all downstream
consumers without any code change.
Version
google-gax@5.0.8 (current latest at time of writing).
Dependency path
@google-cloud/firestore@8.7.0
└─ google-gax@5.0.8
└─ rimraf@5.0.10
└─ glob@10.5.0
└─ minimatch@9.0.9
└─ brace-expansion@2.1.2 ← GHSA-mh99-v99m-4gvg
The same tail is reachable via @google-cloud/pubsub and @google-cloud/tasks,
which also depend on google-gax.
Evidence that rimraf is not used at runtime
Against the published tarball / installed package for google-gax@5.0.8:
$ npm view google-gax@5.0.8 dependencies.rimraf
^5.0.1
$ npm view google-gax@5.0.8 devDependencies.rimraf
# (empty — it is a production dependency)
$ npm view google-gax@5.0.8 scripts --json | grep -i rimraf
# (no matches — no script references rimraf either)
$ grep -rE "require\(.rimraf.\)|from .rimraf." node_modules/google-gax/build/
# (no matches across 47 .js files)So the package neither imports rimraf in its shipped output nor invokes it
from a lifecycle/utility script.
Why consumers cannot easily work around this
The obvious downstream mitigation — overriding brace-expansion to the patched
5.0.8 — breaks google-gax at runtime. minimatch@9.0.9 compiles to:
const brace_expansion_1 = __importDefault(require("brace-expansion"));
return (0, brace_expansion_1.default)(pattern);brace-expansion@5.0.8's CommonJS build sets __esModule: true and exports only
a named expand, so __importDefault does not wrap it and
brace_expansion_1.default is undefined. Every brace-pattern match then throws
TypeError: ... is not a function. (minimatch@10 bumped its major precisely
for this export-shape change.) Note that brace-expansion's advisory range is
<=5.0.7, i.e. every 1.x/2.x/4.x backport is affected — 5.0.8 is the only
patched release, and minimatch@9 cannot consume it.
Consumers are therefore left with a scoped override such as:
"overrides": {
"google-gax": { "rimraf": "^6.1.3" }
}which is safe only because nothing in google-gax actually calls rimraf — but
it is a workaround that every downstream project has to discover and justify
independently.
Requested outcome
Whichever is correct for the package:
- Move
rimraftodevDependencies(or drop it) if it is build-only/unused; or - If it genuinely is required at runtime, bump the declared range to
rimraf@^6,
which resolvesglob@13 → minimatch@10 → brace-expansion@^5.
Related
- Update gaxios to 7.2.0 in gcp-metadata #8868 —
gcp-metadatapinsgaxiosto an exact version;gaxios@7.1.3
carries the samerimraf: ^5.0.1declaration (also unused in its shipped
build/), reaching the tree throughgoogle-auth-library → gcp-metadata.
gaxios@7.3.0droppedrimrafoutright.
Environment
- Node.js 22
- npm 10
- Reproducible from a clean install of
@google-cloud/firestore@8.7.0alone.
Activity
szegheo commentedon Jul 28, 2026
Ran into this via a different path:
@opentelemetry/auto-instrumentations-node(a production dependency in our project) pulls in the same vulnerable chain:Because
gcp-metadata@8.1.4pinsgaxiosto the exact version7.1.3, there's no way to resolve to the fixedgaxios@7.3.0(which droppedrimraf) without a manual override.https://github.com/googleapis/google-cloud-node/blob/main/core/packages/gcp-metadata/package.json#L43
chore(gax): remove unused rimraf dependency (googleapis#8970)
chore(gax): remove unused rimraf dependency (#8970)