WAFs and DDoS Protection for Modern Web Apps
A rented botnet does not care how clean your code is. Here is how WAFs and DDoS protection actually keep web apps online, from anycast scrubbing to rate limit keys.
Von Innovation T Team
Your app does not go down because attackers are brilliant. It goes down because a botnet rented for the price of a pizza pointed a few million requests per second at your login endpoint, and nobody had decided in advance what to drop. A WAF and a DDoS strategy are that decision, written down and enforced at the edge before traffic ever touches your origin.
Know what actually hits you
"DDoS" is not one attack. It is at least three, and they live at different layers with different fixes.
Volumetric (L3/L4). UDP floods, DNS and NTP amplification, SYN floods. The goal is to saturate your pipe or exhaust connection state on your load balancer. Amplification attacks are nasty because the attacker spends one small packet and a misconfigured reflector sends you a response tens of times larger. You cannot absorb this at your origin. If the flood exceeds your uplink, no firewall rule on your box helps: the packets already arrived. The only real answer is capacity that is not yours, meaning an anycast network or a scrubbing provider that eats the flood upstream.
Protocol and state exhaustion. SYN floods that fill connection tables, TLS renegotiation abuse, Slowloris style attacks that open connections and feed them one byte at a time. These do not need much bandwidth. A single VPS can hold thousands of sockets open against a default nginx config. Fixes are protocol level: SYN cookies, aggressive timeouts, connection limits per source, and terminating TLS at an edge that is built for it.
Application layer (L7). HTTP floods that look like real users. GET storms against your most expensive endpoint (search, PDF export, anything that fans out to the database), POST floods against login, credential stuffing, cache-busting requests with random query strings so every hit misses the CDN and lands on your origin. L7 is where most damage happens today because it is cheap, hard to distinguish from real traffic, and targets your slowest code path, not your bandwidth. This is WAF territory.
The decision framework is simple: volumetric attacks are solved with someone else's network, protocol attacks with edge termination and kernel settings, L7 attacks with rules, rate limits, and bot detection. Most teams only think about the third and get taken down by the first.
What a WAF actually does
A web application firewall is a reverse proxy that evaluates every HTTP request against a rule engine before forwarding it. That is the whole trick. The value is entirely in the rules, where they run, and how you operate them.
Managed rules: your baseline, not your strategy
Every serious platform ships managed rulesets: Cloudflare Managed Rules, AWS Managed Rules, and the open source OWASP Core Rule Set (CRS) for ModSecurity and its modern successor Coraza. They catch the commodity layer: SQL injection patterns, XSS payloads, path traversal, known CVE signatures, scanner fingerprints.
Two things matter operationally. First, CRS uses anomaly scoring: each matched rule adds points, and the request is blocked only when the total crosses a threshold. That is far more tolerant of real-world traffic than binary matching, and the paranoia level setting controls the tradeoff. Paranoia level 1 is safe almost everywhere; level 3 and above will flag legitimate JSON bodies and needs serious tuning. Second, managed rules protect against known attack shapes, not your business logic. No managed rule knows that a user should not be able to check out with a negative quantity or enumerate invoice IDs. That layer is covered in our post on API security best practices, and it belongs in your application, not the WAF.
Custom rules: where the real wins are
The highest-value WAF rules we write for clients are boring and specific:
- Block requests to
/wp-login.phpand/xmlrpc.phpon apps that are not WordPress. This alone can cut noise dramatically. - Restrict admin panels by ASN, country, or mTLS instead of hoping the password holds. Never trust network location alone; verify identity on every request.
- Enforce content types: an API that only speaks JSON should reject
multipart/form-dataat the edge. - Challenge or block requests with no
Accept-Language, ancient TLS versions, or JA4 fingerprints that match known bot tooling. TLS fingerprinting is quietly one of the strongest signals available, because faking a browser's TLS stack is much harder than faking a User-Agent string.
A Cloudflare custom rule expression looks like this:
(http.request.uri.path contains "/admin"
and not ip.geoip.asnum in {13335 16509}
and not cf.bot_management.verified_bot)
Readable, versionable, testable. Treat these expressions like code: pull requests, review, staging first.
Positive vs negative security models
Negative model: allow everything, block known-bad. That is managed rules. Positive model: define exactly what is allowed (methods, paths, parameter types, body schemas) and reject everything else. Positive models are dramatically stronger and dramatically more expensive to maintain, because every product change becomes a WAF change. The pragmatic middle: run a negative model globally, and apply positive, schema-based enforcement only on your highest-risk surfaces, like auth, payments, and webhooks. If you already publish an OpenAPI spec, tools can compile it into validation rules, which turns your API contract into an enforcement boundary.
Rate limiting: the most underrated control
Most L7 incidents we see are not exotic. They are one endpoint receiving 200 times its normal traffic. Rate limiting fixes that, but only if you key it correctly.
- Key by IP for anonymous surfaces. Cheap, but weak against distributed attacks and unfair to users behind carrier-grade NAT, which is common across North Africa and the Middle East. Thousands of real users can share one IP.
- Key by session or API token for authenticated surfaces. Precise, and it survives IP rotation.
- Key by target for things like login: limit attempts per account, not just per source, or a distributed credential stuffing run walks right through your per-IP limit.
Set limits from data, not vibes: measure your p99 legitimate request rate per key over a week, then set the limit at a comfortable multiple. At the origin, nginx gives you a solid last line of defense:
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/s;
location /api/auth/ {
limit_req zone=login burst=10 nodelay;
limit_req_status 429;
}
And in AWS WAF, a scoped rate-based rule keeps the flood off the origin entirely:
statement {
rate_based_statement {
limit = 300
aggregate_key_type = "IP"
scope_down_statement {
byte_match_statement {
search_string = "/api/auth"
positional_constraint = "STARTS_WITH"
field_to_match { uri_path {} }
text_transformation {
priority = 0
type = "LOWERCASE"
}
}
}
}
}
Return 429 with a Retry-After header, and make sure your own frontend and mobile clients respect it. In our experience, the first victim of a new rate limit is usually the team's own retry loop.
Failure modes that actually bite
WAF and DDoS setups fail in predictable ways. Design against these from day one.
Exposed origin. You put Cloudflare in front, but your origin still answers to anyone who finds its IP through DNS history, certificate transparency logs, or Shodan. The attacker skips your entire edge. Fix: firewall the origin to accept traffic only from your edge provider's published IP ranges, use authenticated origin pulls (mTLS between edge and origin), and rotate the origin IP after enabling protection, because historical DNS data outlives your migration.
Cache-busting floods. Attackers append random query strings so every request misses cache. Fix: normalize cache keys to ignore unknown parameters, and rate limit on cache misses specifically if your platform supports it.
False positive lockouts. A managed rule update starts blocking your own webhook provider or your biggest customer's proxy. Fix: never deploy rules straight to block. Run new rules in count or log mode for at least a week, review what they would have blocked, then promote. Keep a break-glass allowlist mechanism you can apply in minutes, not hours.
The WAF as a false comfort blanket. A WAF filters request patterns. It does not fix an IDOR, a broken auth flow, or a business logic flaw, and a competent attacker will encode, fragment, and mutate payloads around signature rules. Regular offensive testing is what tells you the difference between coverage and theater; see penetration testing 101 for how to scope that well.
Blocking mode during an incident you cannot see. If your only WAF logs live in a dashboard you never open, you will tune nothing and trust nothing. Ship WAF logs into the same pipeline as your application logs, with the rule ID, action, and matched field on every event.
Choosing your stack
There is no universal answer, but there is a defensible default for most product teams.
- Cloudflare (Pro or Business tier and up). Anycast DDoS absorption included, strong managed rules, expressive custom rules, bot scoring, and rate limiting in one place. The default for most SaaS and content platforms, and the fastest path from zero to protected.
- AWS WAF plus CloudFront plus Shield. The right call when you are deep in AWS, want infrastructure as code from day one, and need WAF decisions co-located with ALB and API Gateway. More assembly required, and cost scales with rules and requests, so watch the bill.
- Fastly with its Next-Gen WAF (formerly Signal Sciences). Excellent when you need advanced edge logic in VCL or Compute and strong L7 detection with low false positives.
- Self-hosted Coraza or ModSecurity with CRS. Full control, no per-request fees, and the only option for some regulated or air-gapped environments. But you own tuning, updates, and scaling, and you get zero volumetric protection: a self-hosted WAF behind a saturated uplink protects nothing.
The honest tradeoff: managed edge platforms trade some control and a recurring bill for absorption capacity you cannot build yourself. Below roughly serious enterprise scale, that trade is nearly always worth taking.
Rollout checklist: from naked origin to defended edge
- Inventory your public surface: every domain, subdomain, API, and third-party callback URL. Attackers enumerate; so should you.
- Put the edge in front: onboard DNS to your provider, enable proxying, and confirm TLS end to end.
- Lock the origin: restrict inbound traffic to edge IP ranges, enable authenticated origin pulls, then change the origin IP.
- Enable managed rules in count mode. Let them observe production traffic for one to two weeks.
- Review the would-be blocks, add targeted exceptions, then flip to blocking mode one ruleset at a time.
- Add rate limits on auth, search, checkout, and any endpoint that touches expensive queries, keyed as described above.
- Write two or three custom rules for your known junk traffic: dead CMS paths, admin geo-fencing, content-type enforcement.
- Wire WAF logs and edge metrics (blocked requests, challenge rates, origin error rates, cache hit ratio) into your observability stack with alerts on sudden shifts.
- Load test through the edge, not around it, so you know your limits fire correctly under pressure.
- Write the runbook: who can toggle "under attack" mode, who can push an emergency rule, and what the escalation path to your provider looks like. Then rehearse it, exactly like the process we describe in the incident response playbook.
Steps 4 and 5 are where most teams cheat, flip everything to block on day one, break checkout for a real customer segment, then turn the whole WAF off in a panic. Count mode first is not caution theater. It is the difference between a control you trust and a checkbox you fear.
Operating it: the part nobody budgets for
A WAF is not a purchase, it is a practice. Rules drift out of date as your app changes. Bot tooling evolves monthly, and residential proxy networks make IP reputation weaker every year. Budget a small, recurring slice of engineering time: review sampled blocks weekly at first, monthly once stable. Track two numbers over time: false positive reports from support, and origin requests per second during attack windows versus calm windows. The first tells you if you are too aggressive, the second tells you if the edge is actually absorbing anything. If both are flat and boring, the system is working. Boring is the goal.
How Innovation T can help
Innovation T designs and operates edge security for production systems: WAF architecture and tuning on Cloudflare and AWS, DDoS resilience reviews, origin lockdown, rate limit design, and the observability to prove it all works. We build the rules, the pipelines, and the runbooks, then train your team to own them.
If your app is one viral moment or one angry botnet away from an outage, let's fix that before it happens. Explore our services or talk to our team about a focused edge security review.
Bereit, mit Innovation T zu bauen?
Ob Sicherheit, Wachstum oder Engineering, unser Team hilft Ihnen, es gut umzusetzen.