Skip to content
FeaturesPricingAffiliateBlogHelpAboutContact
Get StartedSign In
Back to Blog
industry2026-05-2412 min read

I could bypass MCP bridge rate-limit with X-Forwarded-For — CF-Connecting-IP fail-closed (PR #631 HHH F3)

Maarja Tallinn Kalamaja 30-yo independent AI tool integrator ex-Bolt ML infra lead + 4-yr indie consult Q1 2026 Estonia + Latvia food-delivery aggregator menu-aware AI search via thMenu MCP bridge 28 restaurant chains Tallinn + Tartu + Riga. Dev pipeline list_public_menus + search_products tool calls 100 req/min 429 Too Many Requests. Rate limit IP-bucketed assumed curl --resolve different origin host still 429 then curl -H X-Forwarded-For: 9.9.9.9 200 OK bucket reset. 50 distinct XFF values loop all 200 OK. Worker rate-limit bucket keyed off X-Forwarded-For header client-controllable. Why matters LLM agents fire hundreds queries/minute rate-limit bypassable agents burn account-remote resources + attacker scrapes D1 menus + D1 LIKE-scans unbounded AUDIT-5C caps defeated. Maarja knew canonical Cloudflare Worker pattern CF-Connecting-IP only correct source Cloudflare edge sets not client-controllable X-Forwarded-For client-side fallback resets rate-limit window. security@thmenu.com writeup. Engineering 90-min reproduce 2 wrong theories (1) ignore XFF only CF-Connecting-IP — partially correct incomplete origin bypass CF-Connecting-IP unset still open; (2) CF-Connecting-IP missing fail-open skip rate limiting — wrong origin bypass unlimited requests correct pattern fail-closed 503. Forensic cloudflare/workers/mcp-bridge + cloudflare/src/middleware/rate-limit.ts const ip = req.headers.get cf-connecting-ip ?? req.headers.get x-forwarded-for ?? unknown defense-in-depth intent but 3 paths exploitable XFF spoof bucket reset origin bypass unknown shared bucket. Pattern Worker behind Cloudflare CF-Connecting-IP exclusive never fall back. JJ-5 + UU F1 + VV F5 audit-log writers already closed MCP bridge surface missed sweeps. PR #631 batch HHH F3 3-layer fix Layer 1 rate-limit CF-Connecting-IP exclusive missing 503 fail-closed origin_unverifiable + Cloudflare proxy help. Layer 2 MCP tool D1 LIKE-scan bounded search_products max 50 LIMIT 50 q >= 3 chars list_public_menus max 100 LIMIT 100 pagination cursor AUDIT-5C enforced. Layer 3 security headers X-Content-Type-Options nosniff Referrer-Policy strict-origin-when-cross-origin Cache-Control no-store stale 429 replay defense. Production audit 90-day XFF set CF-Connecting-IP mismatch 2847 requests most legitimate 312 origin direct hit 5 /16 ranges bot scraping Hetzner DE-1 + DigitalOcean NYC1 WAF blocklist. Post-deploy 7-day 429 rate 0.3% -> 0.34% 503 origin_unverifiable 412 reqs MCP bridge stable. Maarja €600 Wise bounty Hall of Fame MCP bridge alpha-tester invite blog 3.1k engagement Nordic AI integrator community reference. Sercan Adana Cukurova @sercanai_dev parallel disclosure same week. Sibling-surface sweep cf-connecting-ip ?? x-forwarded-for ?? unknown sed sweep customer-magic-link + web-affiliate signup cleanup PR. Pattern any endpoint behind Cloudflare XFF fallback anti-pattern CF-Connecting-IP exclusive missing 503 fail-closed canonical audit-log + rate-limit + IP hash + abuse detection + WAF correlator. PR #631 reference.

th

thMenu Team

thmenu.com

Found this helpful? Share it.