A request flood never reaches the bot check on your signup form. It fills the origin’s connections first, the health endpoint stops answering, and the app is down. How to set up a web application firewall comes down to 4 moves: put an edge in front, close the direct route, turn on managed rules, add one rate rule.

What a web application firewall is, and what the edge in front of your app does

A web application firewall is an application firewall for HTTP applications: it applies a set of rules to an HTTP conversation, generally covering common attacks such as cross-site scripting and SQL injection. A network firewall sees addresses and ports, not requests. At the edge it sits beside the CDN, DDoS mitigation and rate rules.

That first sentence stays close to OWASP’s definition of a web application firewall, and the rest is my framing. Edge protection is one of the controls in web app security for an AI-built app, and it is the one that decides whether a flood of requests ever reaches your code.

In cyber security terms a WAF does application-level inspection: it reads the method, the path, the headers and the body of each HTTP request and compares them with its rules. A WAF is different from a network firewall because of what each one reads, in my framing: the network firewall decides which addresses may open a connection on which ports and never looks inside. Software firewalls on a laptop or a server do that same network job for one machine; the word covers the host firewall, not a WAF.

The table below is my summary of the five layers a small app usually meets at the edge. None of its cells quotes a provider.

LayerWhat it looks atWhat it stopsWhat it never sees
CDNWhich responses can be cached, and which location should serve themVolume for pages and files it can answer from its cacheRequests for anything it cannot cache, which it passes to the origin
DDoS mitigationNetwork and protocol traffic, before any HTTP request is readNetwork and protocol floodsA request flood that looks like ordinary visitors
WAFEach HTTP request, against its rule setRequests that match a known attack patternRequests sent straight to the origin, and bugs in your own logic
Edge rate rulesHow many requests one client sends in a time windowOne client sending far more than a person wouldTraffic below the threshold, spread over many clients
The origin’s own firewall (a software firewall on the server, or the host’s network rules)Who may connect at all: addresses and portsAnyone who is not the edgeAnything that arrives through the edge

Some hosted platforms already run parts of this edge. Vercel’s platform-wide DDoS mitigation applies to all deployments regardless of plan. Lovable’s security page lists, among other controls, WAF controls and adaptive rate limiting at the IP, user and workspace level for Lovable Cloud. The real work is on apps with their own server, their own API host, or an origin anyone can reach directly by its address.

What goes wrong without it

Four failures show up on small apps with nothing in front of the origin. Each row names what you see first, what is actually happening, and the layer that absorbs it; the rows are my summary.

What you seeWhat is happeningWhat absorbs it
Timeouts for real users, connection-limit errors in the database log, and no sign of an attackerA scraper or an AI crawler requests every page as fast as it can until the database connections run outEdge caching for public pages, one rate rule, the provider’s bot settings
The bill for search, export or AI calls jumps in the same hour as the errorsA small flood aimed at one expensive endpoint costs money per request as well as uptimeA rate rule on that endpoint, plus a spending cap on the metered API
The signup form’s bot check and the API’s rate limiter fail at the same moment as everything elseBoth run inside the app, so a flood that fills the app’s connections takes them down with itAn edge in front, so requests are counted before they reach the app
The access log fills with requests for admin pages and files your app never hadA scanner sweeping the internet found the origin’s address and is trying known pathsManaged rules at the edge, and an origin that stops answering its own address

An origin server overwhelmed by bot traffic is the version I would expect first on a small app: nobody attacked anybody, a crawler simply had no reason to slow down. The second row has a money side as well as an uptime side, and the spending cap belongs with how to cap monthly usage on a metered API.

The third row is the reason the edge has to sit in front, in my reading. A CAPTCHA, a honeypot field or a per-user limit in your API code only runs once the app has accepted the connection and started work, so it protects nothing when the app has no connections left to accept.

If the traffic is real users arriving from a launch or a viral post, the problem is capacity rather than defense, and what to do when your app goes viral starts from that side.

What is a DoS attack, and what does a small app actually face?

A denial-of-service attack is when legitimate users cannot reach a system because of a malicious actor, usually by flooding it with traffic until it cannot respond or crashes. CISA’s 2024 guide names three techniques: volumetric, protocol and application attacks. For a small app, the likelier flood is an unthrottled crawler or one script, not a botnet.

That definition comes from CISA’s explainer on denial-of-service attacks, and the three techniques from CISA, FBI and MS-ISAC’s joint DDoS guide, published March 21, 2024. In cyber security a DoS attack is named by its effect, users locked out, and the method can be anything from one script to a botnet of hijacked devices.

The first two columns of the first three rows follow CISA’s wording; the low and slow row, the example and the last column are my reading for an app with one server and a managed database.

TypeWhat it exhaustsA small app’s exampleWhat a small app can do about it
VolumetricAvailable bandwidth (“attacks aiming to consume available bandwidth”)Traffic big enough to fill the host’s network linkOnly an edge with more capacity than the attacker has
ProtocolNetwork protocol state (“attacks which exploit vulnerabilities in network protocols”), such as half-open connectionsConnection requests that never finish the handshake, leaving ports occupiedRely on the edge or the host’s network layer
ApplicationTargets “specific applications or running services”A script calling search or export in a loopCaching, one rate rule and the WAF’s managed rules
Low and slowConnection slots, held open by a few clients that send very slowlyA handful of clients that each keep a request open for minutesServer timeouts and minimum data rates, with a proxy in front

Low and slow attacks are my grouping inside application attacks, listed apart because the fix is a server setting, not an edge rule. Apache’s mod_reqtimeout, for one, sets “timeout and minimum data rate for receiving requests”, and the server closes the connection when a client falls below it. An owner can check that row against their own server with an open-source tool such as slowhttptest; how to run it is outside this page.

I count four types of DoS: CISA’s three techniques plus the distributed attack, which is any of the three sent from many machines at once. CISA says DDoS attackers often use a botnet, hijacked internet-connected devices, to carry out large scale attacks, and a large scale DDoS attack of that kind is only absorbed by an edge that is bigger than it, in my reading.

A DoS vulnerability is a different thing: a bug that lets one request do far more work than it should, such as a database query with no limit, a regular expression that backtracks on crafted input, or an upload with no size cap. It is fixed in the code. An edge in front only hides it, in my reading: the one request that triggers the bug is well formed, so it looks normal to every rule.

Website defacement protection

Website defacement is an attacker changing what your site shows. The Canadian Centre for Cyber Security says hackers typically inject infected code into the site’s script to take control, and can get in through flaws automated scanning finds, such as SQL injection or cross-site scripting. A WAF can block some of those requests; fixing the code closes the hole.

The Canadian Centre for Cyber Security’s defacement guidance calls web defacement “virtual graffiti or vandalism”, and that is exactly what it means to a visitor: the page they trusted now shows someone else’s content. The useful website defacement examples are its categories of motive rather than named victims; among the reasons it gives are social and political motivations, profit from redirecting web traffic to commercial or infected sites, bandwidth or computing resource piracy, private data theft, and ego.

For an app built on a database, a website defacement attack often means changed rows rather than changed files, in my reading, so the attack can come through an admin screen as easily as through the server. Defacing a website needs a way to write to it, so a web defacement attack is stopped by the same controls as any other break-in. Among the guidance’s tips for protecting a self-hosted site from people who deface web pages:

  • passphrases or strong passwords, so nobody gets in with default log-in credentials
  • fewer privileges on administrator accounts, and accounts removed when people leave
  • monitoring and detection tools that track unauthorized changes to the site
  • regular database backups, and one before every update
  • updated plug-ins and a patched web server
  • secure coding, including properly encoded HTML and URL output against cross-site scripting

The guidance also lists DNS tampering among its further reading. A hijacked DNS or registrar account changes what visitors see without touching your server, and the defense sits with how to add HTTPS to a website and lock the registrar. If a defacing attack has already happened, what to do when your app got hacked is the response, step by step.

How to set up a web application firewall: the edge, the origin, the rules

Setting up a web application firewall for a small app takes 7 steps: check what the host’s edge already does, put the edge in front with DNS, close the direct route to the origin, run managed rules in log mode where the plan has one, allow webhooks and monitors, switch to block with one rate rule, then test a burst.

  1. 01 Find out what your host's edge already does, and whether your origin answers without it
  2. 02 Put the edge in front by pointing DNS at a provider that proxies traffic
  3. 03 Close the direct route to the origin with a tunnel, mutual TLS or an allowlist of the edge's addresses
  4. 04 Turn on the managed rule set in log or count mode where your plan offers one
  5. 05 Allow what must get through: payment webhooks, uptime monitors and your own CI
  6. 06 Switch the managed rules to block and add one rate rule on the expensive endpoints
  7. 07 Run the burst test while a second location watches the origin's health endpoint

Everything below about a provider’s settings comes from that provider’s own documentation, quoted where a setting or a mode is named. Step 4 has a catch on Cloudflare plans below Enterprise, covered in the managed rules section.

Put the edge in front: DNS, proxying, and what your host already gives you

On a platform host the edge is part of the product, and step 2 is already done for the app’s own domain. What differs is which layers you get on which plan: what Vercel’s firewall covers on each plan is answered for Vercel, and whether Netlify has a web application firewall for Netlify.

On your own server or a container host, point the domain at a provider that proxies traffic. Cloudflare’s proxy status docs put the difference plainly: “When a record is Proxied, Cloudflare sits between your visitors and your server”, and when it is DNS-only, “Cloudflare responds with your server’s actual IP address and does not route HTTP/HTTPS traffic through its network.” A proxied record gets a TTL of Auto, set to 300 seconds, which Cloudflare says cannot be edited.

Three things go wrong at this step. HTTPS has to work end to end, from the visitor to the edge and from the edge to the origin, or the second hop travels in plain text. The TTL on the old records should be lowered well before the cutover, which is my working rule, so a mistake rolls back quickly. And every hostname counts: the API subdomain, the admin host and the old name from before a rebrand each need the same treatment, or they stay as side doors (the next section has a case).

Headers can also be added at the edge when the host cannot set them, which matters for the content security policy unsafe-inline fix.

Close the direct route: the Cloudflare IP whitelist and other origin locks

An edge protects nothing while the origin still answers the internet on its own IP. There are 3 locks, strongest first: a tunnel so the origin has no public listener, mutual TLS from the edge, or a firewall that allows only the edge provider’s published IP ranges.

  • A tunnel: the origin makes an outbound connection to the edge and listens on nothing public. Cloudflare’s docs describe its Tunnel as using “outbound-only connections from your origin, so there is no inbound listener”.
  • Mutual TLS: the edge presents a client certificate the origin checks. Cloudflare calls this Authenticated Origin Pulls, which “helps ensure requests to your origin server come from the Cloudflare network” and works on top of its Full or Full (strict) encryption modes, not Off or Flexible.
  • An allowlist: the origin’s firewall accepts web traffic only from the edge provider’s ranges and drops the rest, which Cloudflare’s docs mark as recommended.

In this direction, a Cloudflare IP whitelist is that origin firewall rule accepting each Cloudflare IP range and nothing else; the word in Cloudflare’s current docs is allowlist. The allowlist and mutual TLS both need an origin whose firewall or TLS settings you control, such as your own server or load balancer. On a managed container host, use what the host documents for private networking or inbound rules, and where it documents none, the runbook records the direct route as still open (my reading).

The list behind Cloudflare’s published IP ranges has one source of record: its ranges page says it “is intended to be the definitive source of Cloudflare’s current IP ranges”, the list can be read through the Cloudflare API, and the page keeps a dated history of ranges added and removed. So the Cloudflare IPs you whitelist at the origin are refreshed from that list on a schedule, never pasted once, as my working rule.

To whitelist an IP address on Cloudflare in the other direction, letting one of your own addresses through Cloudflare’s firewall, the tool is an IP access rule; Cloudflare warns that allowing an IP will bypass custom rules, rate limiting rules and WAF Managed Rules for it. If the origin’s address was ever public in DNS, Cloudflare’s docs note it can be found through historical DNS records, so after the lock a new origin IP is the clean finish, in my reading.

Consider a founder who puts the app’s main domain behind a CDN with a proxied record, while the API lives on its own hostname whose record is DNS-only and the server still answers anyone on its public IP. A crawler finds the API hostname and sends its requests there; a DNS-only record answers with the server’s actual IP and does not route HTTP traffic through the edge, so the edge’s rules and analytics never see those requests while the server’s connections fill and its health endpoint stops answering. The fix is the same record proxied and the origin’s firewall allowing only the edge provider’s published ranges; the lesson I take is that an edge protects only the hostnames routed through it, and the origin lock is what closes the rest.

Managed rule sets and the OWASP Top 10: AWS WAF, Cloudflare, Azure and Cloud Armor

A managed rule set is a vendor-maintained group of WAF rules aimed at common web attacks; AWS WAF, Cloudflare, Azure and Google Cloud Armor each offer one. AWS says its core rule set covers some of the high risk vulnerabilities described in OWASP publications such as OWASP Top 10. Log it first where the plan allows, then block.

AWS managed rules in AWS WAF are rule groups AWS maintains and you add to a protection pack (web ACL); the baseline groups are the core rule set, admin protection and known bad inputs. Every cell in the table comes from that provider’s documentation, read in September 2026.

ProviderThe managed rule setWhat the docs say it is based onThe log or count mode
AWS WAFCore rule set (CRS) managed rule group, AWSManagedRulesCommonRuleSetNot stated as the OWASP Core Rule Set in AWS’s docs; they say it covers some OWASP Top 10 vulnerabilitiesCount mode
CloudflareCloudflare Free Managed Ruleset (all plans); Cloudflare Managed Ruleset and Cloudflare OWASP Core Ruleset (Pro and above)OWASP Core Ruleset: Cloudflare’s implementation of the OWASP ModSecurity Core Rule Set; Managed Ruleset: not stated in Cloudflare’s docsLog action, Enterprise plans only
Azure WAF (Application Gateway)Default Rule Set (DRS) 2.2OWASP Core Rule Set 3.3.4Detection mode
Google Cloud ArmorPreconfigured WAF rulesOWASP ModSecurity Core Rule Set, such as version 4.22Preview mode

The sources are AWS WAF’s managed rule groups, Cloudflare’s WAF documentation, Azure WAF’s rule groups and Cloud Armor’s preconfigured WAF rules. AWS WAF’s OWASP Top 10 answer is its core rule set group, with the hedge the capsule above keeps: some of those vulnerabilities, which I would not read as all ten categories. On Cloudflare, Azure and Cloud Armor, the OWASP Top 10 route runs through the OWASP Core Rule Set, in my reading: a project that describes itself as “a set of generic attack detection rules for use with ModSecurity or compatible web application firewalls” and says it aims to protect against a wide range of attacks, including the OWASP Top Ten. Its repository says it is distributed under the Apache Software License version 2.

Plans matter on Cloudflare. “The managed rulesets you can deploy depend on your Cloudflare plan”: the Cloudflare Free Managed Ruleset is “Available on all Cloudflare plans”, while the Cloudflare Managed Ruleset and the Cloudflare OWASP Core Ruleset are marked No on Free and Yes from Pro up. The Log action is “Only available on Enterprise plans”. Azure’s page says its DRS and CRS “are enabled by default in Detection mode” in WAF policies, so on Azure the log step is where you start whether you meant to or not.

The rollout that avoids an outage of your own making: where the plan has a log or count mode, run the new group that way for about a week, which is my working rule, read what it would have blocked, exclude the false positives by rule id and path, then block. AWS’s own testing page says to “test and tune the rules in count mode with your production traffic before enabling them”, and Cloud Armor’s advice is to start “in preview mode”. On Cloudflare below Enterprise there is no log step, so deploy, read the security events for false positives over the first days and add exceptions by rule id and path, as my working rule. No prices here; each provider’s pricing page is the source on the day.

SQL injection and a WAF: a backstop, never the fix

A WAF blocks the SQL injection requests its rules recognize and lets through the ones they do not, so an injectable query stays injectable. The fix is parameterized queries in the code. The WAF buys time between a disclosure and a deploy, and its log shows who is trying.

The query-by-query fix is SQL injection prevention, and a web application firewall in front only narrows the window while that work happens. Output encoding against cross-site scripting has the same shape, and how to mitigate cross-site scripting starts from the code too. The category-by-category review sits with how to test OWASP Top 10 vulnerabilities.

One gap no WAF closes at all: a well-formed request for another customer’s rows looks exactly like a normal one, and the API security checklist answers why a gateway or WAF cannot tell the two apart.

WAF bypass, and RASP versus WAF

A WAF is bypassed in 3 ways: the request goes straight to the origin, the rule is still in log mode or its path was excluded, or the request matches no pattern the rules know. An owner can close the first two. RASP, an agent inside the running app, is an enterprise category a small app can skip.

The first route is the origin lock above. The second is quieter: a group left in count mode after the week was up, or a path excluded to silence one false positive that now skips every rule. My working rule is to read the exclusions list after every change to it. The third route no owner can close at the edge, and it is the reason the code fix matters more than the rule set.

NIST SP 800-53 Rev. 5 describes runtime application self-protection (RASP) in control SI-7(17): it “employs runtime instrumentation to detect and block the exploitation of software vulnerabilities by taking advantage of information from the software in execution.” RASP tools, runtime application self-protection sold as agents that run inside the app, are an enterprise product category, and NIST adds that RASP solutions “can be deployed in either a monitor or protection mode”. Weighing RASP against a WAF for a small app, my answer is a WAF at the edge plus fixed code, and no RASP.

One rate rule at the edge

One edge rule caps requests per client on login, signup, search, export and any endpoint that calls a paid API. Set it well above a real user’s burst, so it only trips on scripts. It is coarse on purpose.

On Cloudflare the rule count depends on the plan: 1 on Free, 2 on Pro and 5 on Business, and on Free the rule matches on the Path field and counts by IP over a 10-second period. So one rule covering the expensive paths fits the Free plan. Cloudflare’s default response code for a rate limiting block is 429 (Too many requests), which is the answer a script should get.

The rule syntax, per-account and per-key limits and nginx’s limit_req belong to rate limiting in an API. Human checks stay inside the app, where the fix for bots submitting our signup form lives. Caching what is safe to cache, with the usual caching strategies for web applications, takes the rest of the load off the origin.

Nginx hardening when the origin is your own server

When nginx is the origin behind the edge, its defaults are generous. From nginx’s core module docs: client_header_timeout and client_body_timeout both default to 60s, keepalive_timeout to 75s, client_max_body_size to 1m (a larger body gets a 413), and server_tokens defaults to on, which puts the nginx version on error pages and in the Server header. At those settings a slow client can wait up to a minute between reads of its body and still keep the connection, which is the low and slow case.

The real client address comes from the realip module, which nginx’s docs say “is not built by default” and is enabled with --with-http_realip_module; set_real_ip_from names the trusted addresses and real_ip_header the header to read, default X-Real-IP. Trust the header only from the edge’s ranges, or anyone can claim any address. On Cloudflare the header is CF-Connecting-IP, which carries “the client IP address connecting to Cloudflare”.

The values below are my working rule for a small app behind an edge, written as a starting point: timeouts near ten seconds, a body limit sized to your largest real upload. The addresses are placeholders.

server {
    # add these to your existing server block; keep its ssl_certificate, server_name and location lines
    listen 192.0.2.10:443 ssl;      # placeholder: the interface the edge or tunnel reaches
    server_tokens off;
    client_header_timeout 10s;
    client_body_timeout 10s;
    keepalive_timeout 15s;
    client_max_body_size 10m;       # placeholder: your largest real upload
    set_real_ip_from 198.51.100.0/24;  # placeholder: one line per range from the edge's list
    real_ip_header CF-Connecting-IP;
}

listen on the one address the edge or the tunnel uses keeps nginx off every other interface, unless another listen line uses the same port on all addresses, since nginx then binds to all of them. The origin’s own request limit, limit_req, is part of the application rate limits above.

PCI DSS and a web application firewall

Requirement 6.4.2 is printed in the PCI Security Standards Council’s SAQ A-EP for PCI DSS v4.0: “For public-facing web applications, an automated technical solution is deployed that continually detects and prevents web-based attacks”, with at least four things. It is installed in front of public-facing web applications and configured to detect and prevent web-based attacks; it is actively running and up to date as applicable; it generates audit logs; and it is configured to either block web-based attacks or generate an alert that is immediately investigated.

The requirement, as the SAQ states it: 6.4.2 supersedes 6.4.1 after 31 March 2025, when 6.4.2 becomes effective, and until then it was a best practice. The good practice, in my reading: a WAF is the usual such solution, and its logs are the audit logs the third item asks for. Whether any of it applies depends on how the app takes cards: a SaaS that sends customers to Stripe’s hosted checkout has a much smaller PCI footprint, and the PCI DSS requirements for a SaaS on Stripe follow from that choice; the testing side is PCI DSS penetration testing.

This is not legal or compliance advice. A WAF meets one line of one requirement; it does not make an app compliant, and an assessor decides what applies.

How to verify it

Edge protection is verified by 7 checks, and two carry the proof: request the origin directly and get refused, then send a short, bounded burst at the edge while a second location polls the origin’s health endpoint, and confirm it stayed green throughout.

  1. 01 Browser first: open the site, then DevTools, the Network tab, the document request, and read its response headers for the edge's own header; keep a screenshot
  2. 02 The direct route is closed: request the origin by its current address from outside and get a refusal or a timeout while the same page loads through the edge; keep both results with the date
  3. 03 The managed rules are set to block, and the security events or rule log for the past week list whatever they matched; keep the setting and the export
  4. 04 The allowlist works: a Stripe test-mode webhook and the uptime monitor both arrive; keep the delivery log
  5. 05 The rate rule answers 429 at the edge once it triggers, and the origin log shows the excess stopping there; keep both logs side by side
  6. 06 The burst: after reading your host's and your edge provider's testing policies, send a short, bounded burst at a cacheable page and the rate-limited endpoint while a second location polls the health endpoint; keep the numbers and the trace
  7. 07 A real user on a phone can still log in and pay; keep the login or order record

Check 1 needs no tools. On Cloudflare the response carries Cf-Ray, which identifies the data center that handled the request, and often Cf-Cache-Status. On Vercel it is server: Vercel and x-vercel-id, and Vercel’s own page notes the server header “can be overridden by other proxies (e.g., Cloudflare)”, so read both.

For check 2, send the request to the origin’s address while keeping the real hostname, from a machine outside your network:

curl -sS -m 10 -o /dev/null -w "%{http_code}\n" --resolve app.example.com:443:192.0.2.10 https://app.example.com/

A refusal or a timeout passes only when 192.0.2.10 stands in for the origin’s current address, as the host’s dashboard shows it, and the same page loads through the edge at the same moment, since a wrong or dead address also times out (my reading). On a platform host whose own edge is the edge from step 1, there is no separate origin to request, and the check records that instead.

For check 3, never improvise attack strings against production. On AWS the documented test is the count-mode run from the managed rules section, before any rule blocks. A test request for a managed rule is not stated in Cloudflare’s managed rules docs, so on Cloudflare the evidence is the rule set’s action setting plus the security events; a quiet week with no matches is not a failure.

For check 4, Stripe publishes Stripe’s webhook IP addresses and says to make sure webhook events originate from one of them; it gives seven days’ notice of changes on its API announce mailing list. If you let those addresses through with a Cloudflare IP access rule, the bypass covers the managed rules and the rate rule too, so allow Stripe’s published addresses only, never a wide range.

For check 5, a few extra origin hits at the start are expected. Cloudflare’s rate limiting docs say counters can lag by up to a few seconds, so “excess requests could still reach the origin before Cloudflare enforces a mitigation action”.

For check 6, read the policies first. AWS’s DDoS simulation testing policy says DDoS simulation testing “must be performed by an AWS Partner Network (APN) Partner that has been pre-approved by AWS”, so a flood-style test on AWS is not something you run yourself. Cloudflare’s scans and penetration testing policy points DoS tests to its guidelines on required notification. A short burst from a load tool, a minute or two against your own domain, is my working rule, and it is a load test, not an attack simulation. Send it with the same kind of tool used for load testing a web application, and have a second location poll the health endpoint the whole time. Pass is the health endpoint green throughout and the edge analytics showing the absorbed requests. Testing only ever targets systems you own.

The Production Hardening Sprint verifies deliverable 3.12 this way: send a load burst at the edge and confirm it is absorbed while the origin’s health endpoint stays green.

Where the sprint does this

Deliverable 3.12 is edge protection: we place a CDN or web application firewall in front of the origin, with rate and abuse rules that absorb floods before they reach the application, and verify it as the verify section above describes. Deliverable 3.10 tests the five highest-risk externally reachable attack surfaces, remediates findings, and delivers the methods and evidence. The production readiness report delivers the result for every scope item, the work completed and its verification evidence; deliverable 13.1 is verified by accounting for all 123 IDs, keeping failures visible until resolved and explaining genuine non-applicable items. Formal third-party certifications and independent audit opinions are separate from these engineering deliverables. The fee covers the engineering work; hosting, paid tools and API usage remain in the client’s accounts, and any required third-party costs are explained before they are enabled. Every item is listed in the published scope.

Common questions about WAFs, CDNs and floods

Is CloudFlare a CDN or WAF?

Both. When a DNS record is proxied, Cloudflare sits between visitors and the server, optimizing, caching and protecting traffic, and it can protect the origin from DDoS attacks; a DNS-only record’s HTTP traffic does not pass through Cloudflare at all. Which managed rulesets you can deploy depends on the Cloudflare plan, as the managed rules table shows.

Is a web application firewall necessary?

Not always: for an origin you run yourself, something in front of it is necessary, and the managed rules are the optional part. That is my verdict. On a platform host the edge is mostly there already, and on any host a WAF is never a substitute for fixing the code it protects.

Does AWS provide a WAF?

Yes. AWS WAF protects resources through a protection pack (web ACL) that you associate with them, including Amazon CloudFront distributions, an Application Load Balancer, an Amazon API Gateway REST API, an AWS AppSync GraphQL API, an Amazon Cognito user pool, an AWS App Runner service and AWS Amplify.

What is DoS vs DDoS?

A DDoS attack is a DoS attack spread across many machines: in CISA’s words, it “occurs when multiple machines are operating together to attack one target”. A plain DoS attack, in my framing, is the same outage caused from one source, which is also why it is easier to block.

What are layer 7 DDoS attacks?

Layer 7 DDoS attacks are the type CISA’s joint guide calls application attacks, “targeting vulnerabilities in specific applications or running services”. Layer 7 as a name for the application layer is my framing, not CISA’s words. They arrive as valid-looking HTTP requests, so caching and rate rules matter more than raw bandwidth, in my reading.

Are DoS attacks still a thing?

Yes. In March 2024 CISA, the FBI and MS-ISAC published a joint guide on understanding and responding to DDoS attacks and urged network defenders to read it to defend against this threat. For a small app, the flood that arrives first is more often a crawler with no manners than a criminal, in my reading.

Do Cloudflare IPs change?

Rarely. Cloudflare’s docs say its IP ranges “do not change frequently” and that changes are added to its list of ranges before being put into production; the ranges page keeps a dated history, and its latest entry was dated September 28, 2023, as of September 2026. Refresh the allowlist from that list on a schedule anyway, which is my working rule.