Protect web applications from OWASP Top 10 and zero-day attacks
Put a firewall in front of a web application, so network lists, WAF, and Bot Manager run in one policy and the origin accepts only Azion's traffic.
A security team protects a customer-facing web application that runs on its own origin, often behind a standalone WAF, appliances, or separate bot and DDoS vendors. Each of those tools holds its own policy, and the origin still answers anyone who finds its address. This page configures one firewall in front of the application, which refuses listed networks, scores every request with WAF and Bot Manager, and lets the origin accept connections from Azion only. The result is measured by the attacks blocked before the origin, the false-positive rate on legitimate traffic, and the time to change a policy.
This use case does not cover API-specific abuse, which Protect public APIs from abuse covers, or account takeover, which Block account takeover on login and checkout flows covers.
Prerequisites
- An application that serves the web application through a connector and a workload. To create them, refer to Applications quickstart.
- A firewall bound to that workload’s deployment. To bind one, refer to Bind a firewall to a workload.
- WAF and Functions turned on in the firewall’s Main Settings › Modules. A new firewall carries WAF off. To turn it on, refer to Set a firewall’s main settings.
- Bot Manager Lite installed from Azion Marketplace, or Bot Manager enabled on the account. To install Bot Manager Lite, refer to Install Bot Manager Lite.
- Access to the firewall of your origin, where the allowlist of Azion’s addresses goes.
- A personal token, for the API tabs. To create one, refer to Personal tokens.
- The values of your application. This page uses
www.example.comfor the domain,198.51.100.7for an address your team already blocks, andwebappas the prefix of every object it creates. Replace each value with yours in every step.
Required products
| The application needs | Which means | Product | Documented in |
|---|---|---|---|
| Sources the team already distrusts refused before any inspection | A network list that a deny rule reads through the Network criterion | Network Shield | Network Lists |
| Requests that carry OWASP Top 10 attack patterns refused before the origin | A WAF rule set that a rule’s Set WAF behavior applies to every request | WAF | WAF quickstart |
| Automated clients told apart from people | A Bot Manager function instance that a Run Function rule runs on every page request | Bot Manager | Run Bot Manager on selected paths |
| An origin that accepts connections only from Azion | Origin IP ACL on the connector, and the Azion Origin Shield prefixes allowed at the origin’s firewall | Origin Shield | Restrict an origin to Azion with Origin IP ACL |
| Security events in the team’s SIEM | A stream of the WAF Events data source to the SIEM’s endpoint | Data Stream | Stream WAF events to a SIEM |
| Each block explained, request by request | The WAF fields of the request’s record, found by its x-azion-request-id | Real-Time Events | Find the WAF score of a blocked request |
DDoS Protection mitigates DoS and DDoS attacks on every workload, before any firewall rule runs, with nothing to create or configure. For the attack types it covers, refer to Attack mitigation.
Reference architecture
This page builds the Web application and API protection (WAAP) perimeter: one firewall policy in front of the workload, with the origin closed to every other path.
Read the diagram from top to bottom. DDoS Protection acts before any rule, and the firewall’s rules then decide each request in order. Network Shield, WAF, and Bot Manager each act only through the rule that calls them, so the order of those rules is the order of the policy. Every request that passes ends at one connector, and the origin’s own firewall closes every other path to it. The dotted edge carries records, not requests: the WAF events leave for the SIEM through Data Stream.
Dataflow
- A visitor’s request reaches the workload on
www.example.com. DDoS Protection assesses it first, and the firewall bound to the workload takes it next. - The first rule compares the client address with the team’s network list and with the Tor exit node list. A listed client receives
403, and no later rule runs. - The second rule hands the request to the WAF rule set. In Blocking, a request whose score reaches a family’s threshold receives
400. - The third rule runs the Bot Manager instance on every request that is not a static asset. A score at the threshold runs the instance’s action.
- A request that no rule stops reaches the application, which forwards it to the origin through the connector. The origin’s firewall accepts the connection because it comes from an
Azion Origin Shieldprefix, and refuses connections from anywhere else. - Data Stream sends each request WAF analyzed to the SIEM. Real-Time Events keeps the record of each request for investigation, joined to a refusal by its
x-azion-request-id.
Components
- firewall: the Platform Resource that enforces the policy. A workload’s deployment names it, and it runs its rules on every request to that workload before the application sees it.
- DDoS Protection: the Feature that mitigates DoS and DDoS attacks on every workload, always on and with nothing to configure. It acts before any firewall rule.
- WAF: scores each request a Set WAF rule hands it against eight threat families, and refuses the request in Blocking mode when a score reaches its threshold. It filters OWASP Top 10 and other attack patterns.
- Bot Manager: scores each request a Run Function rule hands it for signs of automation, and runs the action its instance sets once the score reaches the threshold.
- Network Shield: adds the Network criterion, which matches the client address against a list of addresses, ASNs, or countries. It refuses known-bad sources before WAF and Bot Manager score them.
- application: the Platform Resource that delivers the requests the firewall lets through, and forwards them to the origin.
- connector: the Platform Resource that reaches the origin. Every request that passes the policy ends at it.
- Origin Shield: Origin IP ACL on the connector publishes the
Azion Origin Shieldlist of Azion’s prefixes, which the origin’s firewall allows while it refuses every other source. No client can then reach the origin around the policy. - Data Stream: sends the requests WAF analyzed, with their score, matched rules, and action, to an endpoint the SIEM reads.
- SIEM: the integration that correlates the firewall’s events with the team’s other security sources.
- Real-Time Events: holds the record of each request, with its WAF fields, so a block can be explained from the request ID its client reports.
Configure the network blocks
The network rule runs first, so a source the team already distrusts is refused before WAF and Bot Manager score it. WAF is billed on the requests it scores, and Bot Manager on the requests it evaluates, so a request this rule denies costs neither. The rule reads two lists. webapp-blocked-addresses holds the addresses your team blocks. Azion IP Tor Exit Nodes, list 2, is maintained by Azion, so the rule also matches the exit nodes Azion adds later.
The behavior is Deny (403 Forbidden) rather than Drop. A denied visitor sees a page with a request ID that a person blocked by mistake can report. Once the list refuses only the clients you expect, you can switch to Drop (Close Without Response).
To create the list:
Access Azion Console > Edge Libraries > Network Lists.
In the General section, enter webapp-blocked-addresses as the Name.
In the Network List Settings section, select IP/CIDR. The form opens with ASN selected.
In the List field, enter 198.51.100.7 #blocked by the security team, one address per line.
To create the rule that reads it:
Access Firewalls, select the firewall, then go to the Rules Engine tab.
Enter webapp - deny listed networks.
In the Criteria section, select the Network variable and the matches operator, then select webapp-blocked-addresses in Select a Network.
Add a criterion joined by Or: Network matches Azion IP Tor Exit Nodes.
A client in either list receives 403 once the rule propagates, which takes 6 to 10 minutes for a new rule. A later change to the items of webapp-blocked-addresses reaches traffic in about 100 seconds, with no change to the rule.
Configure the WAF rule set
The rule set webapp-waf scores each request against the eight threat families at medium sensitivity, the level every family starts at. The rule that applies it matches ${request_uri} starts with /, which matches every request. A criterion on the query string would skip every POST that carries its payload in the body.
The rule starts in Logging. A request that reaches a threshold is recorded and still served, and those records are the only description of your traffic as the rule set sees it. Move the rule to Blocking once 3 days of Tuning hold no request that should have been served.
To create the rule set:
Access Azion Console > Edge Libraries > WAF Rules.
In the General section, enter webapp-waf as the Name.
The Threat Type Configuration section lists the eight threat families, each at Sensitivity Medium.
To apply it:
Access Firewalls, select the firewall, then go to the Rules Engine tab.
Enter webapp - apply webapp-waf.
In the Criteria section, select Request Uri, starts with, and /.
In the Behaviors section, select Set WAF, then webapp-waf and Logging.
The rule set scores every request the network rule lets through, and records what would have been blocked. To read those records and turn a false positive into an exception, refer to Tune a WAF rule set. To move the rule to Blocking, refer to Switch a rule set to blocking.
Configure Bot Manager scoring
The Bot Manager instance starts in observation mode: action is allow, so it refuses nothing, and internal_logs is 2, so every request writes a report line. Run it for 24 to 72 hours, long enough to cover peak hours, weekly crawlers, and overnight jobs. threshold is 18, the value Bot Manager documents to start from. While action is allow, the threshold only sets the classified label of each line. log_tag is webapp-observe, so each line names this instance.
The rule that runs the instance excludes static assets, because an image or a stylesheet is not a client, and each one is a request Bot Manager bills. It names no path, so every other request of the application is scored.
Create the instance and the rule as Run Bot Manager on selected paths describes, with these values:
-
Instance:
webapp-bot-observe, with these arguments: -
Rule:
webapp - score page requests, with one block of criteria: the static-asset exclusion,Request Uridoes not match the guide’s expression. The rule carries no block of paths. -
Behavior: Run Function with
webapp-bot-observe.
Every page request is scored and served, and each one writes a report line tagged webapp-observe. When the window closes, read the scores, set threshold in the gap between the legitimate and the automated clusters, and set action to deny. For the procedure, refer to Monitor and calibrate Bot Manager.
Configure origin allowlisting
Origin IP ACL on the connector gives the account the Azion Origin Shield network list, which holds every IPv4 and IPv6 prefix that Azion’s infrastructure uses to connect to origins. Your origin’s firewall then allows those prefixes and denies every other source, so a client that connects to the origin’s address directly never reaches the application around the firewall policy above.
The allowlist is the procedure that Restrict an origin to Azion with Origin IP ACL describes, run on the connector that reaches the web application’s origin. The origin’s firewall holds the IPv4 and the IPv6 prefixes of the list, and denies every other source.
Verify the setup
Wait for the rules to propagate before you judge a result: a new rule reaches traffic 6 to 10 minutes after it is saved, and answers alternate until it settles. Repeat each request until the answer holds.
-
A listed source is refused before inspection. From an address in
webapp-blocked-addresses, request the home page:The command prints
403. -
WAF scores an attack pattern. From an address that is not listed, send an injection-shaped query string:
In Logging, the application answers as usual. After the switch to Blocking, the same request receives:
The response’s
x-azion-request-idfinds the request in theworkloadEventsdataset of Real-Time Events, wherewafMatchnames the internal rules that matched,1009and1013for this query string. For the lookup, refer to Find the WAF score of a blocked request. -
Bot Manager scores page requests. Send a request with no user agent, which is what a scripted client sends:
The request is served, and the
functionConsoleEventsdataset of Real-Time Events holds a line that opens with[Bot-Protection][webapp-observe] Report:, carrying itsscoreandmatched_rules. For the query, refer to the Bot Manager quickstart. -
Static assets are not scored. Request an asset, such as
https://www.example.com/styles/main.css. No report line taggedwebapp-observeappears for it. -
The origin refuses direct connections. From a host outside Azion, connect to the origin’s own address. The origin’s firewall refuses the connection, while requests to
www.example.comstill reach the application. -
Security events reach the SIEM. In Real-Time Events, the Data Stream data source lists each send of the stream, and a Status Code of
200means the SIEM’s endpoint accepted the batch.
Measuring results
| Metric | Where to read it | What working looks like |
|---|---|---|
| Attacks blocked before the origin | Threats vs Requests on the WAF dashboard of Real-Time Metrics, which splits analyzed requests into blocked threats, logged threats, and allowed requests. Refer to Secure dashboards | After the switch to Blocking, the threats the rule set finds appear as blocked rather than logged |
| False-positive rate on legitimate traffic | The Tuning tab of webapp-waf, which lists the requests that reached a threshold over the last 3 days. Refer to Tuning | No request you recognize as legitimate, and no exception older than the request that produced it |
| Time to change a policy | The time from saving a change to the answer holding at a repeated request, as in Wait for a change to propagate | A list change holds in about 100 seconds, and a new rule in 6 to 10 minutes |
Best practices
- Put the network rule first. The firewall runs its rules in order, and no later rule runs for a request a deny stops. A listed source then never reaches WAF or Bot Manager, which both bill on the requests they see. For rule order, refer to How Firewall works.
- Change a list, not a rule, for a source that changes often. A change to a list’s items reaches traffic in about 100 seconds, a new rule in 6 to 10 minutes, and the list adds nothing to the rules your plan includes per firewall.
- Keep the WAF rule’s criterion on the request URI.
${request_args}matches.*reads as every request and skips every request without a query string.${request_uri}starts with/matches them all, as in Match the request, not its query string. - Raise one threat family at a time. Raising several families at once produces false positives together, with nothing to say which raise produced which block. For the steps, refer to Raise the sensitivity of one threat family.
- Keep IPv6 in the origin allowlist, and update it within 7 days. The list carries IPv6 prefixes for every data center, and the servers behind a new prefix go into production 7 days after Azion publishes it. An allowlist that misses either refuses connections Azion opens. For the update, refer to List updates.