Application Security

Combined interactive edition of the four Application Security classes: Cloudflare Setup (AppSec 1), Build and Tune Effective Security Rules (AppSec 2), Bot and Abuse Mitigation (AppSec 3), and Stop Attacks in Real Time (AppSec 4).

⚠ Read this first

These labs run against your assigned Cloudflare-managed lab zone on sxplab.com. Every task is performed in the Cloudflare dashboard or from a terminal against your assigned domain. Fill in your lab slug in the form below before you start, so every command and address in this guide is ready to copy and run.

Typographical Conventions

This guide uses the following conventions to distinguish between user input, system output, and explanatory notes.

ConventionMeaningExample
BoldNames of selectable items in the interfaceClick Save to apply the change.
MonospaceText that you enter and code examplesEnter the command: whoami
Result textStep results, explanations, expected outputOperation completed successfully.
ItalicsContextual notes explaining "why" a task is necessaryThis keeps the service from restarting mid-test.
<in angle brackets>A per-student variable, filled in by the reader.Run dig A <lab-slug>.sxplab.com and press Enter.

How to Use This Guide

This is one guide split into four parts, one per Application Security class: Part 1 (Cloudflare Setup), Part 2 (Build and Tune Effective Security Rules), Part 3 (Bot and Abuse Mitigation), and Part 4 (Stop Attacks in Real Time). Lab numbers restart in each part, matching the individual class guides. Work the parts in order; later parts assume the rules and state created by earlier ones.

About the step numbers and checkboxes. Every instruction has a number (like 4.2.1) and a checkbox next to it. These are optional and are only a visual aid: as you work, you will flip back and forth between this guide and the dashboard, and it is easy to lose your place. Tick a box when you finish a step so you can glance back and instantly see where you were. Checking a box just highlights the step and remembers it in your browser; it does not submit anything, unlock anything, or report anywhere. You do not have to use them at all.
Start here ☛ Fill in your lab values

This is the most important box in the guide. Enter the slug for your assigned lab domain. Your full domain is <lab-slug>.sxplab.com, so if your domain is happy-balancer.sxplab.com you enter happy-balancer. Every matching placeholder across the guide, including inside the copy blocks, is substituted with your value, so when you click Copy you get a real, ready-to-run command instead of a <placeholder>. Values save to your browser only; nothing is sent anywhere.

Why These Labs

Why you are doing all of this: These four parts walk through the same job a security engineer does when protecting a real web application, in the order you would actually do it. First you make sure traffic is going through Cloudflare at all and is encrypted (Part 1). Then you learn to see attacks in the analytics, write precise rules to stop them, and tune those rules so you block the bad traffic without blocking real customers (Part 2). Then you defend against bots and abuse targeting logins and APIs (Part 3). Finally you respond to a live attack in real time and measure whether your mitigation actually worked (Part 4). Every individual step below also has its own short "Why" note explaining what that specific action accomplishes, so you are never just clicking without knowing the reason.

AppSec 1 - Cloudflare Setup: From Start to Best Practices

Lab 1: DNS Investigation & Configuration

In this lab, you will diagnose and fix a DNS configuration that exposes an origin server and bypasses Cloudflare's security and performance services.

Scenario: You received support ticket NET4815. Users report that www.<lab-slug>.sxplab.com is slow and displays a privacy warning, while the root site works normally.

1.1 Investigate with dig

Compare the A-record response for www with the response for the root domain:

dig A www.<lab-slug>.sxplab.com
dig A <lab-slug>.sxplab.com

Record the returned IP addresses and query times.

Why: The www record is intentionally configured as DNS Only, so it returns the origin address instead of Cloudflare addresses. That is why it is slow and shows a privacy warning: traffic is going straight to the origin and bypassing Cloudflare.
Note: If dig is unavailable, use https://dnschecker.org to compare the responses.

1.2 Fix the Exposed DNS Record

In the Cloudflare dashboard, select your lab domain.

Go to DNS > Records.

Find the www record.

Change Proxy status from DNS Only to Proxied.

Run the two lookups again and confirm that www now returns Cloudflare addresses.

Verify: After the change, dig A www.<lab-slug>.sxplab.com returns Cloudflare anycast addresses (the same kind the root domain returns), not the origin IP, and the privacy warning is gone.

Lab 2: SSL/TLS Configuration

In this lab, you will observe how Full (Strict) protects the connection to the origin, then restore the lab's required state.

2.1 Induce the SSL Error

Go to SSL/TLS > Overview.

Open Configure encryption mode if the encryption-mode options are not already visible.

Change the mode from Full to Full (Strict).

Open your lab domain in another tab.

Record the Cloudflare error code that appears. The published lab currently expects 525: SSL handshake failed.

Why: The exact error depends on the origin's TLS state. A 525 means the TLS handshake failed. A 526 means the origin presented a certificate that Cloudflare could not validate in Full (Strict) mode. This shows that Full (Strict) refuses to trust an origin that cannot prove its identity.

2.2 Restore the Lab State

Return to SSL/TLS > Overview.

Change the mode back to Full.

Confirm that the site loads.

Verify: The lab site loads again without the Cloudflare SSL error.
Note: This reset is specific to the lab. In production, install a valid origin certificate and retain Full (Strict).

Lab 3: Verifying Traffic in Analytics

3.1 Find the Error in Analytics

Go to Analytics > HTTP Traffic.

Add an Edge status code filter for the code you recorded in Lab 2. The published scenario expects 525; use 526 if that is what your lab origin produced.

Confirm that you can find the error generated in Lab 2.

Adjust the time range if the request is not immediately visible.

Verify: The Lab 2 error appears in HTTP Traffic once you filter by that edge status code.

Lab 4: Enabling the Web Application Firewall (WAF)

4.1 Enable and Verify the Cloudflare Managed Ruleset

Go to Security > Settings.

Filter the settings for Web application exploits.

Turn on Cloudflare managed ruleset.

Go to Security > Analytics > Events.

Find the pre-existing local-file-inclusion scanner traffic and inspect the action Cloudflare took.

4.2 Deploy OWASP Safely

Return to Security > Settings and turn on OWASP Core.

Select View ruleset.

Configure Paranoia Level 1 with Action = Log.

Save the configuration.

Why: Starting in Log lets you inspect matches before enforcing a broader ruleset against production traffic. OWASP is score-based, so logging first shows you what it would catch before it can block a real customer.

4.3 Test the Logging Rule

Run this simulated SQL-injection request against your assigned domain:

curl "https://<lab-slug>.sxplab.com/?id=1'%20OR%20'1'='1'"

Return to Security > Analytics > Events, find the request, and confirm that its action is Log. Inspect the matched rule and anomaly-score details. If the event is not visible, check the request, time range, ruleset configuration, and threshold.

Verify: The simulated injection appears in Events with action Log, and you can open it to see the matched OWASP rule and anomaly score.

Appendix: Lab Command Reference

The dig commands used in this class, for quick reference:

dig A www.<lab-slug>.sxplab.com
dig A <lab-slug>.sxplab.com
dig NS <lab-slug>.sxplab.com

AppSec 2 - Build and Tune Effective Security Rules

You are a security engineer at AcmeCorp. You will investigate suspected scraping, build a mitigation, resolve a rule conflict, and tune the rules without blocking legitimate users.

Lab 1: Assess - The Threat Hunt

Scenario: Marketing reports that competitors appear to receive AcmeCorp's pricing and product data almost immediately. Investigate whether automated scraping is targeting the product catalogue.

1.1 Investigate the Traffic

Go to Security > Analytics > Traffic.

Use Add filter to investigate source ASN, URI path, user agent, and status code.

Look for high-volume traffic from one non-residential network targeting /services/.

Confirm that the requests return 200, indicating that content is being served.

Record the suspected scraper ASN for Lab 2.

Why: The lab traffic uses ASN 16509, Amazon AWS (AMAZON-02). Earlier material incorrectly called ASN 16509 DigitalOcean; DigitalOcean uses different ASNs. Confirming the ASN gives you the first candidate signal to build a rule on.

Lab 2: Build - The First Attempt

2.1 Create the Block Rule

Go to Security > Security rules > Custom rules.

Select Create rule.

Configure the rule:

Deploy the rule.

Why: This first rule is intentionally broad so you can test its interactions and false positives. You will refine it over the next labs.

Lab 3: Test - The Rule Conflict Puzzle

3.1 Check the Result

Go to Security > Analytics > Events.

Filter for BLOCK - Scraping ASN.

Inspect whether the target scraper traffic is being blocked.

Return to Security > Security rules > Custom rules and read the rules from top to bottom.

Identify BYPASS - Main Customer Geo above your new rule. Its Skip action catches the scraper's geography before the Block rule can evaluate it.

3.2 Fix the Order

Move BLOCK - Scraping ASN to position 1, above BYPASS - Main Customer Geo.

Return to Security > Analytics > Events.

Confirm that your rule now blocks the target traffic.

Why: Custom rules run in order, top to bottom. A Skip rule above your Block rule short-circuits evaluation, so rule order is itself a security control.
Verify: After the move, Events shows the scraper ASN traffic blocked by BLOCK - Scraping ASN.

Lab 4: Tune - The False Positive (Part 1)

Scenario: A legitimate customer using a VPN from the same ASN is blocked. Use a zero-risk rollout to find a more selective signal.

4.1 Switch to Log

Edit BLOCK - Scraping ASN.

Change Action from Block to Log.

Rename it LOG - Scraping ASN.

Save the rule.

Why: Switching to Log is a zero-risk rollout: it stops blocking the legitimate VPN customer immediately while you keep collecting the data you need to find a more precise signal.

4.2 Compare the Traffic

Go to Security > Analytics > Events and filter for the logging rule.

Compare the user agents:

4.3 Refine the Rule

Edit the rule and require both conditions:

(ip.src.asn eq <SCRAPER_ASN>) and (http.user_agent eq "python-requests")

Review representative Log matches before enforcement.

Rename the rule BLOCK - Scraping ASN+UA.

Change Action to Block and deploy it.

Verify: The refined rule matches the python-requests scraper from that ASN but no longer matches the VPN customer's normal browser user agent.

Lab 5: Tune - The False Positive (Part 2)

The trusted site monitor uses the same ASN and user agent as the scraper but has a known static source address.

5.1 Create the Trusted-Service List

Go to Manage account > Configurations > Lists.

Create an IP list named site_monitor_ips.

Add 34.83.115.243.

Save the list.

Why: A list gives you a reusable, named set of trusted addresses you can reference in an expression as $site_monitor_ips, so you can carve out a known-good client without weakening the block rule.

5.2 Create the Skip Rule

Return to the lab domain and go to Security > Security rules > Custom rules.

Create BYPASS - Site Monitor IP.

Use this expression:

(ip.src in $site_monitor_ips)

Select Skip and include All remaining custom rules.

Deploy the rule and move it to position 1.

Keep BLOCK - Scraping ASN+UA in position 2.

Verify: The site monitor at 34.83.115.243 is skipped, and the scraper is still blocked by the position-2 rule.

Lab 6: Tune - Rule Set Hygiene

6.1 Fix the Over-Broad Rule

Find BLOCK - RU Android 5.0 in Custom rules.

Its OR condition blocks all Russian traffic and all Android 5 users globally.

Change OR to AND so both intended conditions must be true:

(ip.geoip.country eq "RU") and (http.user_agent contains "Android 5.")

Save the rule.

Review the remaining rules for other logic that is broader than the AcmeCorp requirements.

Why: An OR between two conditions matches when either is true, so this rule was blocking far more than intended. Changing it to AND enforces the actual requirement: Russian traffic on Android 5, not everyone in Russia and every Android 5 user worldwide.

Lab 7: Proactive Security - Rate Limiting

7.1 Rate-Limit the Contact Form

Go to Security > Security rules > Advanced rate limiting rules.

Create a rule with these settings:

Deploy the rule and monitor its events for intended and unintended matches.

Why: Rate limiting is proactive: instead of blocking a known bad signal, it caps how often any single client can hit an abuse-prone endpoint, which stops form spam and brute force without needing to identify the attacker first.

Appendix: Lab Reference

ItemValue
Scraper ASN16509 - Amazon AWS
Scraper user agentpython-requests
Site monitor IP34.83.115.243

AppSec 3 - Bot and Abuse Mitigation

You are a security engineer at AcmeCorp. A distributed credential-stuffing attack is targeting the admin login. You will enable bot signals, investigate the traffic, deploy a broad first mitigation, test its rule order, correct a mobile-app false positive, and add rate-based defenses.

Exercise Starting State

The AppSec 3 lab environment is provisioned with a planned starting state. It uses the following Custom rules:

OrderRuleActionPurpose
1BYPASS - Site Monitor IPSkipTrusted-service exception
2BLOCK - Scraping ASN+UABlockAppSec 2 scraper mitigation
3BLOCK - DE Android 5 UABlockTuned legacy rule
4BYPASS - Main Customer GeoSkipBroad US Skip that creates the Lab 4 conflict
5BLOCK - bot UABlockLow-priority user-agent rule
This planned state uses the preloaded BLOCK - DE Android 5 UA rule. That differs from the BLOCK - RU Android 5.0 exercise in Part 2 (AppSec 2); treat the AppSec 3 lab account's preloaded state as authoritative for this class.

The credential-stuffer traffic is US-origin, targets /admin and /v1/login, has bot score 1, produces 401 responses, and carries leaked-credential signals. The legitimate mobile app uses AcmeCorp-Mobile/2.1.0, targets /v1/orders, and also has bot score 1.

Lab 1: Establishing Baseline Protections

1.1 Verify Leaked-Credential Detection

Go to Security > Settings.

Open the Fraud group.

Verify that Leaked credentials detection is on.

1.2 Enable JavaScript Detections and Model Updates

In Security > Settings, open the Bot traffic group.

Enable JavaScript Detections.

Verify that automatic Bot Management model updates are on.

Why: JavaScript Detections and up-to-date Bot Management models give Cloudflare stronger, fresher signals (like bot score) to work with, which is what the later rules in this part rely on.

1.3 Manage a Verified Crawler

Open AI Crawl Control from the domain sidebar.

Open the Security tab.

Find the Crawlers table.

Review the verified crawlers.

Set a non-essential search crawler to Block for this exercise.

Lab 2: Assess - The Threat Hunt

2.1 Investigate the Login Traffic

Go to Security > Analytics > Traffic.

Filter URI path to /admin.

Analyze the filtered data for these signals:

Confirm that the combined evidence is consistent with credential stuffing.

Note: If the leaked-credential field is unavailable or unpopulated, continue using the other evidence rather than assuming a result.

Lab 3: Build - The First Mitigation

Why start broad: This lab plan deliberately starts with a broad rule so the later mobile-app false positive can occur, which is the whole point of the tuning labs that follow.

3.1 Create the Broad Challenge Rule

Go to Security > Security rules > Custom rules.

Create a rule with these settings:

Deploy the rule at the bottom of the Custom rules list.

Note: Do not add path conditions yet. In a production rollout, start in Log and review representative matches before challenging traffic.

Lab 4: Test - Verify the Rule

This lab adds a rule-order conflict to work through.

4.1 Trace and Fix the Order

Go to Security > Analytics > Events and filter for CHALLENGE - low bot score.

Observe that the new rule is not handling all target traffic.

Open Account > Observe > Investigate > Trace.

Trace a bot-score-1 request from the US.

Confirm that BYPASS - Main Customer Geo skips the request before the bottom-position challenge rule can run.

Return to Custom rules.

Move CHALLENGE - low bot score to position 2, immediately below BYPASS - Site Monitor IP.

Redeploy and confirm in Events that the challenge now fires.

Why: Trace simulates a request through your configuration and shows exactly which rule acts on it first, which is how you prove the broad US Skip was short-circuiting your challenge rule.

Lab 5: Tune - The False Positive

The broad rule also challenges AcmeCorp's legitimate mobile application.

5.1 Identify the False Positive

Go to Security > Analytics > Events.

Filter for events from CHALLENGE - low bot score.

Find the legitimate traffic with both characteristics:

Confirm that this is wanted automated traffic and therefore a false positive.

Lab 6: Advanced Tuning and Mitigation

6.1 Refine the Custom Rule

Edit CHALLENGE - low bot score.

Change the expression to:

(cf.bot_management.score eq 1) and (http.request.uri.path eq "/admin")

Rename the rule CHALLENGE - Admin Credential Stuffing.

Save it in position 2.

Confirm that /admin bot traffic remains challenged and /v1/orders mobile-app traffic no longer matches.

Why: Adding the path condition narrows the rule to the endpoint under attack, so the legitimate mobile app hitting /v1/orders with the same bot score is no longer caught.

6.2 Create a Leaked-Credential Rate Limit

Go to Security > Security rules > Advanced rate limiting rules.

Create a rule with these settings:

Deploy the rule.

6.3 Protect the Orders API

Create another Advanced Rate Limiting rule with these settings:

Deploy the rule.

Why: Counting by JA4 fingerprint ties the rate limit to the client's TLS fingerprint rather than IP alone, which holds up better against a distributed attack that rotates addresses.

Expected End State

The tuned Custom rule is CHALLENGE - Admin Credential Stuffing in position 2. The two new Advanced Rate Limiting rules are ARL - Leaked Credential Attempts and ARL - API Scraping. The other preloaded rules remain in place.

AppSec 4 - Stop Attacks in Real Time

You are a security administrator for AcmeCorp, and the site is under an active application-layer attack.

The Incident Response Framework

Use this framework throughout the exercise:

  1. Assess: Understand what is happening.
  2. Define: Identify the threat and security gap.
  3. Respond: Deploy a precise mitigation.
  4. Evaluate: Verify the result and check legitimate-user impact.
Note: The obsolete custom-rule, WAF Trace, and Internal Health Monitor flow is not part of this guide.

Lab 1: Assess - Initial Triage

Scenario: Customers report slow search results and 503 errors. An executive asks you to enable Under Attack Mode immediately.

1.1 Observe the Blunt Control

Open the lab domain's Overview page.

Enable Under Attack Mode.

Refresh the lab site and observe the challenge applied broadly to visitors.

Disable Under Attack Mode immediately.

Why: Broad challenges can disrupt APIs, webhooks, payment services, mobile apps, and other non-browser clients. Use them only when the incident evidence and business impact justify the tradeoff.

1.2 Investigate the Traffic

Go to Security > Analytics > Traffic.

Use Add filter to investigate these signals:

Confirm a large traffic spike concentrated on /search with increased 503 responses and concentrated source characteristics.

Lab 2: Define - The Threat and The Gap

2.1 Define the Attack

Classify the incident as application abuse intended to impact service. The clients repeatedly invoke the compute-intensive search function rather than sending an undirected network flood.

2.2 Audit the Existing Defense

Go to Security > Security rules > Advanced rate limiting rules.

Open Block high rate of requests.

Confirm that it targets the search path.

Inspect the threshold. The planted starting value is 200 requests in 1 minute, which is too high to protect the lab application's search function effectively.

Why: The security gap is an inadequately tuned rate limit, not a broken rate-limiting feature. The control exists; its threshold is just set too high to help.

Lab 3: Respond - Tune the Mitigation

3.1 Determine a Data-Driven Threshold

Return to Security > Analytics > Traffic.

Keep the analysis focused on /search.

Open Request rate analysis.

Use the graph and slider to identify the maximum one-minute request rate for clients that are not attacking the endpoint.

Select a threshold above the observed non-attacking clients and below the abusive clients. Do not assume one fixed threshold fits another application.

3.2 Update the Existing Rule

Return to Security > Security rules > Advanced rate limiting rules.

Edit Block high rate of requests.

Keep the rule targeted to /search.

Set the one-minute threshold to the value derived from Request rate analysis.

Change the action from Block to Managed Challenge.

Extend the mitigation timeout so clients that exceed the rate remain challenged for an appropriate period.

Save the rule.

Why: Tune the existing Advanced Rate Limiting rule instead of creating a new Custom rule. Managed Challenge lets real users through with a challenge while still throttling the automated abuse.

Lab 4: Evaluate & Activate

4.1 Confirm the Result in Analytics

Return to Security > Analytics > Traffic.

Compare the periods before and after the rule update.

Confirm that abusive /search traffic and 503 responses decrease.

Test normal search behavior in the lab application.

4.2 Test the Rate Limit

Run the loop against your assigned domain:

for i in {1..100}; do
  curl -so /dev/null -w "${i} - %{http_code}\n" \
    "https://<lab-slug>.sxplab.com/search/?q=testing"
done

Observe when the response changes after the configured rate is exceeded. Confirm the corresponding mitigation events rather than relying only on terminal status codes.

4.3 Evaluate Events and Client Solve Rate

Go to Security > Security rules > Advanced rate limiting rules.

Use the rule's Events link or graph to open Security > Analytics > Events filtered to the rule.

Inspect when and how often the rule acted.

Review the rule's Client Solve Rate (CSR).

Why: CSR is the percentage of issued challenges that clients solved. A high CSR can indicate that the rule is challenging too much legitimate traffic. Interpret it with event samples, endpoint behavior, and support reports; a low CSR alone does not prove that no legitimate client was affected.

4.4 Tune and Prepare

Discuss how an attacker might distribute requests across more clients or move to another expensive endpoint. Record those hypotheses before changing controls.

As a proactive follow-up, go to Manage account > Notifications.

Select Add.

Review the available security and traffic notifications for the account.

Configure an appropriate notification if the lab account permits it.

Note: Notifications improve awareness but do not replace application monitoring or an incident-response process.

Exercise State

StateRuleMatchThresholdAction
InitialBlock high rate of requestsSearch path200 requests / 1 minuteBlock
FinalSame existing ruleSearch pathData-derived requests / 1 minuteManaged Challenge with extended mitigation timeout

No new Custom rule, Internal Health Monitor exception, or WAF Trace step is used.

Resources

Reference material for all four classes. External links open Cloudflare documentation in a new tab.

End of Lab Guide.