DDoS Protection and Web Application Firewalls: Defending the Edge
Learn DDoS attack categories (volumetric, protocol, application-layer), mitigation architecture with scrubbing centers and anycast, WAF rules for SQLi/XSS/CSRF, bot detection, and CAPTCHA tradeoffs.
Edge Defense as a Design Constraint
Everything else in your security design — authentication, encryption, careful authorization — assumes traffic actually reaches your application in a legitimate state. DDoS attacks and malicious application traffic try to break that assumption before it's even true: either by drowning your infrastructure in volume so nothing gets through, or by disguising attack payloads as ordinary requests so they slip past every layer behind the edge.
This is the layer that sits in front of everything else. Get it wrong, and encryption, auth, and careful data modeling never even get a chance to matter.
DDoS and application attacks are different problems solved at different layers. A volumetric flood is solved with capacity and routing, not application code. A SQL injection attempt is solved with request inspection, not more bandwidth. Conflating the two leads to over-provisioning bandwidth while staying exposed to injection, or the reverse.
The Three Categories of DDoS Attacks
"DDoS" is really three distinct attack families that share only one trait: they come from many distributed sources at once, making simple IP blocking ineffective.
| Category | Target | Example Attacks | Typical Scale | Primary Defense Layer |
|---|---|---|---|---|
| Volumetric | Network bandwidth | UDP floods, DNS amplification, NTP amplification | Gbps–Tbps | Scrubbing centers, anycast, upstream ISP |
| Protocol | Server/network stack resources | SYN flood, slowloris, ping of death | Packets/sec, connection slots | Network edge, load balancer, OS-level tuning |
| Application-layer (L7) | Expensive application logic | HTTP flood on search/login/checkout, cache-busting requests | Requests/sec | WAF, rate limiting, application logic |
Each requires a fundamentally different mitigation because each exhausts a different resource.
Volumetric Attacks: Flooding the Pipe
Volumetric attacks aim to consume all available bandwidth before traffic even reaches your servers. A classic example is DNS amplification: the attacker sends small, spoofed DNS queries to open resolvers, which reply with much larger responses directed at the victim — a small request becomes a large flood, amplifying the attacker's effective bandwidth by 10-100x.
No amount of application-level tuning helps here — if the pipe is full, legitimate packets are dropped right alongside attack packets, indiscriminately. This has to be absorbed or filtered before it reaches your network, which is why it's solved at the ISP/CDN/scrubbing-center layer, not in your application.
Protocol Attacks: Exhausting Connection State
Protocol attacks target the resource limits of the network or transport stack rather than raw bandwidth.
- SYN flood: the attacker sends a flood of TCP SYN packets but never completes the handshake (never sends the final ACK). Each half-open connection consumes a slot in the server's connection table until it times out. Enough half-open connections and the server can't accept new legitimate connections.
- Slowloris: the attacker opens many HTTP connections and sends headers extremely slowly, just fast enough to avoid a timeout, keeping each connection open indefinitely. A modest number of slow connections can exhaust a web server's worker/thread pool, since each thread sits blocked waiting for a request that never finishes.
Both exploit the stateful nature of TCP — the server has to hold resources open, hoping the client finishes. Mitigations include SYN cookies (don't allocate state until the handshake completes), connection timeouts tuned aggressively, and load-balancer-level connection limits per source.
Application-Layer Attacks: Expensive Requests, Not Big Ones
Application-layer (L7) attacks look like completely normal HTTP traffic — valid TCP connections, valid HTTP requests — just a huge volume of them, often targeting the most expensive endpoints deliberately: search (triggers a full-text query), login (triggers a password hash comparison), or any endpoint with cache-busting query parameters (guarantees a cache miss on every request, forcing origin computation every time).
Application-layer attacks are the hardest to distinguish from legitimate traffic, and the cheapest for the attacker to run. A few thousand requests per second against a /search?q=<random> endpoint from a botnet of ordinary-looking residential IPs can take down a service that could easily survive a much larger volumetric attack at the network layer, because each request forces real backend work.
DDoS Mitigation Architecture
Effective DDoS defense is layered — each attack category is absorbed at the layer built to handle it, well before it reaches application code.
Anycast Routing
Anycast announces the same IP address from many points of presence (PoPs) around the world. Instead of all traffic converging on one data center, each client's traffic routes to its nearest PoP via normal BGP routing. This means a volumetric attack's traffic gets automatically spread across dozens of geographically distributed locations rather than concentrating on a single link — turning a single 500 Gbps flood aimed at one IP into, say, fifty PoPs each absorbing 10 Gbps, which is a load each can typically handle.
This is the mechanism behind why large CDNs (Cloudflare, AWS Shield, Akamai) can credibly claim to absorb multi-terabit attacks: no single data center ever sees the full attack.
Scrubbing Centers
A scrubbing center sits inline (or traffic is rerouted to it during an attack) and inspects traffic at the packet level, dropping malformed packets, spoofed-source packets, and known attack signatures, while passing legitimate traffic through — typically with some added latency during an active attack. This is where SYN flood mitigation (SYN cookies), protocol validation, and volumetric filtering happen, before traffic ever reaches your load balancers.
Rate Limiting at the Edge
Once traffic passes the network-layer defenses, rate limiting at the edge (CDN or API gateway) handles the application-layer flood case — capping requests per IP, per token, or per session before they reach the origin. This guide has a dedicated deep dive on the algorithms behind this — token bucket, sliding window, distributed counting with Redis — see Rate Limiting and Throttling for the mechanics. The point for DDoS purposes is where rate limiting sits: as close to the edge as possible, so rejected requests never consume origin capacity.
Multi-Vector Attacks
Real-world attacks frequently combine categories rather than sticking to one. A common pattern: an attacker opens with a volumetric flood to trigger the target's DDoS mitigation and consume defender attention, then follows with a low-volume, high-precision application-layer attack against a specific endpoint once the noise has drawn eyes elsewhere. This is exactly why the layered architecture above matters — each layer needs to hold on its own, because a single layer failing shouldn't cascade into the others being blind.
Design each defense layer to fail independently. If your WAF/rate-limiting layer depends on the scrubbing center to have already filtered "the noise," a multi-vector attack that saturates the scrubbing center can leave the application layer effectively undefended at the exact moment it's under the most precise attack.
Web Application Firewalls (WAF)
A WAF sits in the request path — typically at the CDN/edge layer, before requests reach your application — and inspects the content of each request (headers, body, query parameters) against rules designed to catch malicious payloads, not just malicious volume.
Signature-Based vs Anomaly-Based Detection
| Approach | How it Works | Strengths | Weaknesses |
|---|---|---|---|
| Signature-based | Matches requests against known attack patterns (regex rules for ' OR 1=1, <script>, etc.) | Fast, low false-positive rate for known attacks, easy to reason about | Blind to novel/obfuscated attacks not matching a known signature |
| Anomaly-based | Builds a baseline of "normal" traffic and flags statistical deviations | Can catch zero-day and obfuscated attacks | Higher false-positive rate, needs tuning per application, harder to explain a block |
Most production WAFs (AWS WAF, Cloudflare WAF, ModSecurity) run primarily signature-based rule sets — often maintained as managed rule groups (e.g., OWASP Core Rule Set) — with anomaly-based or ML-based scoring layered on top for traffic that doesn't match a known signature outright.
Rule Examples
SQL injection — block requests where a parameter contains SQL syntax that has no business appearing in user input:
# Simplified WAF rule (ModSecurity-style)
SecRule ARGS "@rx (?i)(union\s+select|or\s+1=1|;\s*drop\s+table)" \
"id:1001,deny,status:403,msg:'SQL Injection Attempt'"
XSS (Cross-Site Scripting) — block script tags and event-handler injection in fields that will be rendered as HTML:
SecRule ARGS "@rx (?i)(<script[^>]*>|onerror\s*=|javascript:)" \
"id:1002,deny,status:403,msg:'XSS Attempt'"
CSRF (Cross-Site Request Forgery) — a WAF's role here is narrower: it can enforce that state-changing requests (POST/PUT/DELETE) include a valid Origin/Referer header matching your domain, but the real fix is application-level — CSRF tokens tied to the user's session, validated server-side on every state-changing request. A WAF is a backstop, not the primary defense for CSRF.
Managing False Positives
A WAF that blocks legitimate traffic is its own kind of outage — and it's a real operational risk, not a theoretical one. A regex tuned to catch union select can just as easily block a legitimate customer support message that happens to contain those words in prose, or a product search for a band literally named with SQL-like syntax. Production WAF deployments handle this with:
- A "log-only" / monitor mode for new rules before switching them to block — run the rule for a period, review what it would have blocked, and confirm it's not catching legitimate traffic before enforcing it.
- Per-application rule tuning, since a rule set calibrated for a typical CRUD API can be too aggressive for an application that legitimately handles code snippets, markup, or SQL-like text as user content (a developer tool, a forum for DBAs).
- An exception/allowlist path for specific routes or fields known to trigger false positives, scoped as narrowly as possible rather than disabling the rule globally.
A WAF is a layer, not a substitute for secure application code. Parameterized queries stop SQL injection categorically; a WAF signature stops the specific patterns it knows about. Attackers routinely find encodings and obfuscations (double URL-encoding, comment injection, case variation) that slip past signature rules. Ship both — parameterized queries and output encoding in the application, WAF rules as an additional layer that catches attacks before they even reach that code.
Bot Detection
A meaningful share of application-layer attacks — credential stuffing, scraping, inventory hoarding, fake account creation — comes from bots, not from a single malicious human clicking fast. Distinguishing bot traffic from real users is a distinct problem from rate limiting or WAF signature matching.
Why Simple IP Blocking Fails
A botnet distributes requests across thousands of residential IP addresses (often compromised home devices or bought/rented proxy pools), so each individual IP sends a handful of requests — well under any reasonable rate limit — while the aggregate traffic is an attack. Blocking by IP either misses the attack (limits set high enough to allow the aggregate through per-IP) or blocks real users who happen to share an IP with a bot (NAT'd office networks, mobile carrier IPs).
Behavioral Fingerprinting
Rather than looking at "how many requests from this IP," behavioral bot detection looks at how a client behaves:
- Client-side signals: mouse movement patterns, timing between form fields, whether JavaScript actually executes and reports back consistent browser/device fingerprints, whether the TLS handshake's cipher/extension ordering matches a real browser (JA3/JA3S fingerprinting) rather than a scripted HTTP client.
- Request-pattern signals: perfectly uniform timing between requests (humans are irregular; scripts are often suspiciously consistent), requests that skip pages a real user flow would hit (going straight to checkout without ever loading a product page), or missing headers a real browser always sends.
- Reputation signals: IP/ASN reputation (known VPN/proxy/hosting-provider ranges are disproportionately bot traffic vs. residential ISP ranges), and cross-request correlation (this device fingerprint has hit 400 different accounts in the last hour).
None of these signals alone is reliable — they're combined into a risk score, and the response scales with the score: low risk passes through untouched, medium risk gets a lightweight challenge, high risk gets blocked or hard-CAPTCHA'd.
CAPTCHA Strategies
CAPTCHA is the most visible bot-defense tool, and also the most user-hostile — every CAPTCHA shown to a real user is friction, and friction has a measurable conversion cost.
The Friction Tradeoff
| Approach | User Friction | Bot Resistance | When to Use |
|---|---|---|---|
| Always-on CAPTCHA | High — every user, every time | High | Rarely justified as a default; acceptable for very low-frequency, very high-value actions (e.g., account recovery) |
| Risk-based / adaptive CAPTCHA | Low — only shown when risk score is elevated | High where it matters | Standard approach for login, signup, checkout |
| Invisible challenge (e.g., reCAPTCHA v3, Turnstile) | Near-zero — runs in the background, scores the request | Moderate–high, degrades gracefully | Default first layer on most public forms |
| Honeypot fields | Zero for real users | Low — only catches unsophisticated bots | Cheap supplementary layer, not a primary defense |
The general pattern in modern systems is risk-based, invisible-first: run an invisible challenge or behavioral score on every request, and only escalate to a visible, interactive CAPTCHA when the risk score crosses a threshold — a new device, an unusual velocity of requests, a mismatched fingerprint. This keeps friction near zero for the overwhelming majority of legitimate users while still gating the traffic that actually looks suspicious.
A CAPTCHA shown to every user on every login is a conversion cost paid on every single legitimate request, in exchange for stopping bots that are a small fraction of total traffic. The better trade is almost always: invisible scoring for everyone, interactive challenge only for the traffic that scores as risky. When asked to design bot defense in an interview, lead with risk-based escalation, not "add a CAPTCHA."
Detecting and Responding to an Attack in Progress
Mitigation architecture only helps if you know an attack is happening. Most DDoS damage isn't from the attack itself outlasting your defenses — it's from the gap between the attack starting and someone (or something) noticing.
Signals Worth Alerting On
| Signal | What It Suggests |
|---|---|
| Sudden spike in requests/sec with normal per-IP volume | Distributed application-layer attack (botnet) |
| Spike in SYN packets without matching ACK completion | SYN flood |
| Origin CPU/connection-pool saturation with edge traffic still nominal | Slow-connection attack (slowloris-style) bypassing edge counters |
| Error rate (5xx) climbing while request rate is flat | Attack targeting one expensive endpoint, not overall volume |
| Traffic concentrated on endpoints with no caching (search, login, checkout) | Deliberate targeting of expensive code paths |
Automated vs Manual Response
Most managed DDoS protection (AWS Shield, Cloudflare) automatically engages stronger scrubbing and rate limiting once traffic crosses a learned baseline, without a human in the loop — this matters because volumetric and protocol attacks escalate in seconds, faster than any on-call engineer can react. Application-layer attacks tend to need a mix: automated rate limiting and WAF rule matching handle the obvious cases, but a genuinely novel attack pattern (a botnet mimicking real user behavior closely) often needs a human to identify the targeted endpoint and add a temporary, narrower rule — for example, tightening the rate limit specifically on /search rather than globally, to avoid degrading the experience for users who aren't part of the attack.
Common mistake: only monitoring at the edge. Edge-level metrics can look calm during a slow, low-and-slow attack (like slowloris) that never trips a request-rate threshold but still exhausts origin connection pools one held-open connection at a time. Instrument the origin's own resource saturation (connection pool usage, worker thread availability), not just edge request counts.
DDoS and WAF Checklist
- Volumetric attacks are absorbed upstream via anycast + scrubbing center, not at the origin
- Protocol-level defenses (SYN cookies, aggressive connection timeouts) are enabled at the load balancer/edge
- Rate limiting is enforced at the edge/CDN layer, not only inside the application (see the Rate Limiting & Throttling guide for algorithm choice)
- A WAF sits in front of the application with an actively maintained signature rule set (e.g., OWASP Core Rule Set)
- WAF rules are treated as a layer on top of secure application code (parameterized queries, output encoding), never a substitute for it
- Bot detection combines behavioral, request-pattern, and reputation signals — not IP blocking alone
- CAPTCHA is risk-based and invisible-first, escalating to interactive challenges only for elevated-risk traffic
- CSRF protection is enforced at the application layer (session-bound tokens), with the WAF as a secondary check
- Alerting exists for traffic anomalies (sudden request-rate spikes, error-rate spikes) so an attack in progress is visible quickly
What to Remember for Interviews
- Three DDoS categories, three layers of defense: volumetric (anycast/scrubbing), protocol (SYN cookies/connection limits), application-layer (WAF/rate limiting).
- Distributed attacks defeat simple IP blocking — that's true for volumetric botnets and for bot traffic alike; behavioral and reputation signals are what actually work.
- A WAF inspects content, a rate limiter counts volume — know the difference and don't conflate them when asked to "protect the API."
- Signature-based WAF rules catch known patterns; anomaly-based catches the unknown — production systems layer both.
- CAPTCHA is a friction/security tradeoff — the strong answer is risk-based and invisible-first, not "add a CAPTCHA to the login form."
- WAF and secure code are complementary, not substitutes — parameterized queries stop SQL injection categorically; a WAF rule stops what it recognizes.
Practice: If asked "how would you protect a public API from DDoS," structure the answer by layer — network (anycast/scrubbing), transport (SYN cookies), edge (WAF + rate limiting), application (secure code, CAPTCHA where justified) — rather than jumping straight to "add a WAF." Naming the layered architecture is what distinguishes a strong answer from a buzzword answer.