WAF Rate Rules for Mobile: Avoid Blocking Carrier-Grade NAT Users

WAF Rate Rules for Mobile: Avoid Blocking Carrier-Grade NAT Users

Carrier-grade NAT means thousands of legitimate mobile users share a handful of public IPs. A blunt IP rate rule that works for desktop web will false-positive entire cell towers during a product launch—while distributed credential stuffing still slips through on residential proxies. Tune for identity signals, not only source IP.

⚡ TL;DR: Prefer composite keys (IP + device/app attestation + route) over raw IP limits for mobile APIs. Use higher IP thresholds with lower per-token/session limits. Label CGNAT ranges; separate login endpoints. Pair with Multi-Tenant Rate Limits, SSRF Hardening in Node, and Continuous Path Verification.

Why IP-only rules fail on mobile

Desktop: 1 user ≈ 1 IP → IP rate ≈ user rate
Mobile CGNAT: 500–5000 users ≈ 1 IP → IP rate false-positives
Botnets: 1 attacker ≈ many IPs → IP rate false-negatives

AWS WAF rate-based rules aggregate on IP by default. For mobile APIs behind API Gateway or CloudFront, that aggregation is often the wrong unit.

Layered limits that survive CGNAT

{
  "Name": "login-per-ip-loose",
  "Priority": 10,
  "Action": { "Block": {} },
  "Statement": {
    "RateBasedStatement": {
      "Limit": 2000,
      "AggregateKeyType": "IP",
      "ScopeDownStatement": {
        "ByteMatchStatement": {
          "SearchString": "/v1/auth/login",
          "FieldToMatch": { "UriPath": {} },
          "PositionalConstraint": "STARTS_WITH",
          "TextTransformations": [{ "Priority": 0, "Type": "NONE" }]
        }
      }
    }
  }
}
// App-layer token bucket (Redis) keyed by user/device — true fairness
// See multi-tenant rate limits deep-dive for cluster-safe bucketing
const key = `rl:login:${deviceId || "anon"}:${route}`;
await redis.tokenBucket(key, { rate: 5, burst: 10, windowMs: 60_000 });
Layer Key Typical budget
WAF IP (login path only) High (e.g. 1k–2k/5m)
Edge JA3 / app attestation Medium
App userId / deviceId Strict (auth abuse)
App password hash + IP Credential stuffing

✅ Strict app-layer identity limits + loose IP backstop.
❌ Single global 100 requests / 5 min / IP on all routes.

Labeling and exceptions

Maintain a supervised list of known CGNAT / mobile ASN ranges for dashboards—not for blanket allowlists (attackers abuse those too). Prefer challenge actions (CAPTCHA/managed challenge) over hard blocks on borderline IPs for interactive clients; keep hard blocks for clearly abusive automation signatures.

# CloudWatch metric filters: track WAF BlockedRequests by rule + country
# Page when BlockedRequests spike correlates with mobile conversion drop
# (canary: continuous path verification on /auth and /pay)

Wire synthetic canaries from mobile egress ASNs so you detect self-DoS before App Store reviews spike—see Continuous Path Verification.

Closing checklist

  • [ ] Login and write routes have separate WAF rate scopes
  • [ ] IP limits are high enough for CGNAT; identity limits are strict
  • [ ] App attestation / device keys feed app-layer buckets
  • [ ] Challenge preferred over block for borderline interactive traffic
  • [ ] Metrics join WAF blocks with conversion / auth success
  • [ ] Mobile ASN canaries exercise auth and pay paths

Related reading

Last updated on September 11, 2026


Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply