Skip to content

chore(deps): unblock ip-address 10.4.0 via express-rate-limit 8.6.2 - #161

Merged
yumike merged 1 commit into
mainfrom
chore/ip-address-via-express-rate-limit
Aug 9, 2026
Merged

chore(deps): unblock ip-address 10.4.0 via express-rate-limit 8.6.2#161
yumike merged 1 commit into
mainfrom
chore/ip-address-via-express-rate-limit

Conversation

@yumike

Copy link
Copy Markdown
Contributor

Closes Dependabot alerts #121 and #41.

AlertSeverityAdvisoryNeeds
#121highGHSA-mwp4-54f8-5fhr / CVE-2026-69192Address4 decodes leading-zero octets as decimal while resolvers decode them as octal, allowing SSRF and trust-boundary bypass10.3.1
#41mediumGHSA-v2v4-37r5-5v8g10.1.1

Why a lockfile bump alone couldn't fix it

@backstage/backend-defaults
→ express-rate-limit: ^8.2.2 → resolved 8.3.1
→ ip-address: "10.1.0" ← exact pin

An exact pin admits no upgrade, so yarn up -R ip-address was a dead end — it would only have lifted the other consumer (socks, ^10.0.1) and left a second vulnerable copy behind for express-rate-limit. Same shape as the undici problem in #153.

What this does

express-rate-limit 8.5.1 relaxed the pin to ip-address: ^10.2.0, and backend-defaults already declares ^8.2.2, which accepts 8.6.2 (current latest). Two passes:

yarn up -R express-rate-limit # 8.3.1 → 8.6.2, relaxes the pin
yarn up -R ip-address # collapses the remaining socks copy

The first step is genuinely not sufficient on its own — it leaves the tree split:

After step 1
ip-address@^10.2.010.4.0 ✅
ip-address@^10.0.1 (socks)10.1.0 ⚠️ still vulnerable

The second pass collapses both descriptors onto one entry at 10.4.0.

PackageBefore → After
express-rate-limit8.3.1 → 8.6.2
ip-address10.1.0 → 10.4.0 (single copy)

Lockfile-only: 9 insertions, 8 deletions, no manifest touched. express-rate-limit 8.6.2 also adds debug: ^4.4.3, already present in the tree.

Verification

express-rate-limit is live Express middleware and this crosses three minor versions, so it got more than a lockfile glance:

CheckResult
yarn install --immutable✅ no drift
rw-backend tests, run in isolation✅ 38 suites / 301 tests
yarn typecheck
yarn build
yarn lint
yarn test (full)✅ 588 tests
yarn format:check
yarn workspace app build✅ (CI skips this)

The 301 rw-backend tests drive real Express routers through supertest, which is the direct evidence that middleware behaviour is unaffected.

Scope

Worth being clear about the risk class: express-rate-limit uses ip-address to parse client IPs for rate limiting — that is a trust boundary, and an octal/decimal parsing discrepancy there is a rate-limit evasion primitive, with SSRF named explicitly in the advisory.

It reaches this repo only through @backstage/backend-defaults, which is a devDependency of plugins/rw-backend and a dependency of the private packages/backend. So it is not in any published plugin's graph — but it is one of the more materially exploitable classes seen in this backlog, and worth closing rather than leaving.

🤖 Generated with Claude Code

Alerts #121 (high, GHSA-mwp4-54f8-5fhr / CVE-2026-69192 — Address4 decodes
leading-zero octets as decimal while resolvers decode them as octal, allowing
SSRF and trust-boundary bypass) and #41 (medium) were both unreachable:
express-rate-limit 8.3.1 pins ip-address to exactly "10.1.0", and an exact pin
admits no upgrade.
express-rate-limit 8.5.1 relaxed that to "^10.2.0", and @backstage/backend-
defaults already declares "^8.2.2", which accepts 8.6.2. Re-resolving it therefore
lifts ip-address, and a second pass collapses the remaining socks copy
("^10.0.1", left at 10.1.0 by the first step) onto the same version:
express-rate-limit 8.3.1 -> 8.6.2
ip-address 10.1.0 -> 10.4.0 (single copy, was two mid-way)
express-rate-limit uses ip-address to parse client IPs for rate limiting, which
is itself a trust boundary — an octal/decimal parsing discrepancy there is a
rate-limit evasion primitive. It reaches us only through backend-defaults, a
devDependency of rw-backend and a dependency of the private demo backend, so it
is not in any published plugin's graph.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@yumike
yumike merged commit 254fe07 into mainAug 9, 2026
1 check passed
@yumike
yumike deleted the chore/ip-address-via-express-rate-limit branch August 9, 2026 05:43
Sign up for freeto 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

@yumike