Detection rules › Panther
Panther rules: cloudflare
| Rule | Severity |
|---|---|
| Cloudflare Bot High Volume | low |
| Cloudflare L7 DDoS | medium |
| Cloudflare React2Shell RCE Attempt Detected | high |
Cloudflare Bot High Volume
#Monitors for bots making HTTP Requests at a rate higher than 2req/sec
Detection logic
from panther_cloudflare_helpers import cloudflare_http_alert_context
def rule(event):
# Bot scores are [0, 99] where scores >0 && <30 indicating likely automated
# https://developers.cloudflare.com/bots/concepts/bot-score/
return all(
[
event.get("BotScore", 100) <= 30,
event.get("BotScore", 100) >= 1,
]
)
def title(event):
return (
f"Cloudflare: High Volume of Bot Requests "
f"to [{event.get('ClientRequestHost', '<NO_REQ_HOST>')}]"
)
def alert_context(event):
return cloudflare_http_alert_context(event)
Rule specification
AnalysisType: rule
Filename: cloudflare_httpreq_bot_high_volume.py
RuleID: "Cloudflare.HttpRequest.BotHighVolume"
DisplayName: "Cloudflare Bot High Volume"
Enabled: false
LogTypes:
- Cloudflare.HttpRequest
Tags:
- Cloudflare
Severity: Low
Description: Monitors for bots making HTTP Requests at a rate higher than 2req/sec
Runbook: Inspect and monitor internet-facing services for potential outages
Reference: https://developers.cloudflare.com/waf/rate-limiting-rules/request-rate/
DedupPeriodMinutes: 60 # 1 hour
Threshold: 7560 # 2req/sec is 7200 + 5% for just-in-case
SummaryAttributes:
- ClientIP
- ClientRequestUserAgent
- EdgeResponseContentType
- ClientCountry
- ClientRequestURI
Stages and Predicates
Fires on Cloudflare.HttpRequest events when all of the conditions below hold.
Condition
BotScoreis at most30BotScoreis at least1
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
BotScore | ge |
| field:"BotScore" kind:ge value:"1" |
BotScore | le |
| field:"BotScore" kind:le value:"30" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
ClientRequestHost |
Response runbook
Inspect and monitor internet-facing services for potential outages
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"BotScore": 29,
"CacheCacheStatus": "miss",
"CacheResponseBytes": 76931,
"CacheResponseStatus": 404,
"CacheTieredFill": false,
"ClientASN": 63949,
"ClientCountry": "gb",
"ClientDeviceType": "desktop",
"ClientIP": "142.93.204.250",
"ClientIPClass": "noRecord",
"ClientRequestBytes": 2407,
"ClientRequestHost": "example.com",
"ClientRequestMethod": "GET",
"ClientRequestPath": "",
"ClientRequestProtocol": "HTTP/1.1",
"ClientRequestReferer": "https://example.com/",
"ClientRequestURI": "",
"ClientRequestUserAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36",
"ClientSSLProtocol": "TLSv1.3",
"ClientSrcPort": 28057,
"ClientXRequestedWith": "",
"EdgeColoCode": "LHR",
"EdgeColoID": 373,
"EdgeEndTimestamp": "2022-05-07 18:53:13",
"EdgePathingOp": "wl",
"EdgePathingSrc": "macro",
"EdgePathingStatus": "nr",
"EdgeRateLimitAction": "",
"EdgeRateLimitID": "0",
"EdgeRequestHost": "example.com",
"EdgeResponseBytes": 17826,
"EdgeResponseCompressionRatio": 4.55,
"EdgeResponseContentType": "text/html",
"EdgeResponseStatus": 404,
"EdgeServerIP": "",
"EdgeStartTimestamp": "2022-05-07 18:53:12",
"OriginIP": "",
"OriginResponseBytes": 0,
"OriginResponseStatus": 0,
"OriginResponseTime": 0,
"OriginSSLProtocol": "unknown",
"ParentRayID": "00",
"RayID": "707c283ab88274cd",
"SecurityLevel": "med",
"WAFAction": "unknown",
"WAFFlags": "0",
"WAFMatchedVar": "",
"WAFProfile": "unknown",
"WAFRuleID": "",
"WAFRuleMessage": "",
"WorkerCPUTime": 0,
"WorkerStatus": "unknown",
"WorkerSubrequest": false,
"WorkerSubrequestCount": 0,
"ZoneID": 526503649,
"p_any_domain_names": [
"https://example.com/",
"example.com"
],
"p_any_ip_addresses": [
"142.93.204.250"
],
"p_any_trace_ids": [
"00",
"707c283ab88274cd"
],
"p_event_time": "2022-05-07 18:53:12",
"p_log_type": "Cloudflare.HttpRequest",
"p_parse_time": "2022-05-07 18:54:31.922",
"p_row_id": "a6e3965df054cfcdbdccf3ec10a134",
"p_source_id": "2b9fc5ae-9cab-4715-8683-9bfbdb15a313",
"p_source_label": "Cloudflare"
}
Cloudflare L7 DDoS
#Layer 7 Distributed Denial of Service (DDoS) detected
Detection logic
from panther_cloudflare_helpers import cloudflare_fw_alert_context
def rule(event):
return event.get("Source", "") == "l7ddos"
def title(_):
return "Cloudflare: Detected L7 DDoS"
def alert_context(event):
return cloudflare_fw_alert_context(event)
def severity(event):
if event.get("Action", "") == "block":
return "Info"
return "Medium"
Rule specification
AnalysisType: rule
Filename: cloudflare_firewall_ddos.py
RuleID: "Cloudflare.Firewall.L7DDoS"
DisplayName: "Cloudflare L7 DDoS"
Enabled: true
LogTypes:
- Cloudflare.Firewall
Tags:
- Cloudflare
- Variable Severity
Severity: Medium
Description: Layer 7 Distributed Denial of Service (DDoS) detected
Runbook: Inspect and monitor internet-facing services for potential outages
Reference: https://www.cloudflare.com/en-gb/learning/ddos/application-layer-ddos-attack/
DedupPeriodMinutes: 60 # 1 hour
Threshold: 100
SummaryAttributes:
- Action
- ClientCountry
- ClientIP
- ClientRequestUserAgent
Stages and Predicates
Fires on Cloudflare.Firewall events when the condition below holds.
Condition
Sourceisl7ddos
Response runbook
Inspect and monitor internet-facing services for potential outages
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"Action": "skip",
"ClientASN": 55836,
"ClientASNDescription": "RELIANCEJIO-IN Reliance Jio Infocomm Limited",
"ClientCountry": "in",
"ClientIP": "127.0.0.1",
"ClientRequestHost": "example.com",
"ClientRequestMethod": "GET",
"ClientRequestPath": "/main.php",
"ClientRequestProtocol": "HTTP/1.1",
"ClientRequestQuery": "",
"ClientRequestScheme": "http",
"ClientRequestUserAgent": "Fuzz Faster U Fool v1.3.1-dev",
"Datetime": "2022-05-10 06:36:57",
"EdgeColoCode": "DEL",
"EdgeResponseStatus": 403,
"Kind": "firewall",
"MatchIndex": 0,
"Metadata": {
"dos-source": "dosd-edge"
},
"OriginResponseStatus": 0,
"OriginatorRayID": "00",
"RayID": "7090a9da88e333d8",
"RuleID": "ed651449c4a54f4b99c6e3bf863134d5",
"Source": "l7ddos"
}
Cloudflare React2Shell RCE Attempt Detected
#Detects React2Shell (CVE-2025-55182) RCE attempts blocked by Cloudflare WAF
Detection logic
from panther_cloudflare_helpers import cloudflare_fw_alert_context
# Cloudflare Rule IDs for CVE-2025-55182
REACT2SHELL_RULE_IDS = [
"33aa8a8a948b48b28d40450c5fb92fba", # Managed Ruleset
"2b5d06e34a814a889bee9a0699702280", # Free Ruleset
]
def rule(event):
rule_id = event.get("RuleID", "")
return rule_id in REACT2SHELL_RULE_IDS
def title(event):
client_ip = event.get("ClientIP", "<UNKNOWN_IP>")
return f"Cloudflare React2Shell (CVE-2025-55182) Exploit Detected from [{client_ip}]"
def alert_context(event):
return cloudflare_fw_alert_context(event)
Rule specification
AnalysisType: rule
Filename: cloudflare_react2shell_rce_attempt.py
RuleID: "Cloudflare.Firewall.React2Shell.RCE"
DisplayName: "Cloudflare React2Shell RCE Attempt Detected"
Enabled: true
LogTypes:
- Cloudflare.Firewall
Tags:
- Cloudflare
- RCE
- React2Shell
- CVE-2025-55182
Severity: High
Description: Detects React2Shell (CVE-2025-55182) RCE attempts blocked by Cloudflare WAF
Runbook: |
1. Query Cloudflare Firewall logs for all requests from the ClientIP in the 6 hours before and after the alert to identify attack patterns
2. Check if the ClientIP is associated with known threat actors, scanning infrastructure, VPN services, or proxy networks
3. Search for other React2Shell attempts from this IP or targeting the same ClientRequestHost in the past 7 days
Reference: https://blog.cloudflare.com/cloudflare-protection-against-cve-2025-55182-react2shell
SummaryAttributes:
- Action
- ClientCountry
- ClientIP
- ClientRequestUserAgent
- ClientRequestHost
Stages and Predicates
Fires on Cloudflare.Firewall events when the condition below holds.
Condition
RuleIDis one of33aa8a8a948b48b28d40450c5fb92fba,2b5d06e34a814a889bee9a0699702280
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
RuleID | in |
| field:"RuleID" kind:in |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
ClientIP |
Response runbook
1. Query Cloudflare Firewall logs for all requests from the ClientIP in the 6 hours before and after the alert to identify attack patterns
2. Check if the ClientIP is associated with known threat actors, scanning infrastructure, VPN services, or proxy networks
3. Search for other React2Shell attempts from this IP or targeting the same ClientRequestHost in the past 7 days
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"Action": "block",
"ClientASN": 13335,
"ClientASNDescription": "CLOUDFLARENET",
"ClientCountry": "us",
"ClientIP": "1.2.3.4",
"ClientRequestHost": "example.com",
"ClientRequestMethod": "POST",
"ClientRequestPath": "/api/upload",
"ClientRequestProtocol": "HTTP/2",
"ClientRequestQuery": "",
"ClientRequestScheme": "https",
"ClientRequestUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Datetime": "2025-12-16 10:30:00",
"EdgeColoCode": "SFO",
"EdgeResponseStatus": 403,
"Kind": "firewall",
"MatchIndex": 0,
"OriginResponseStatus": 0,
"RayID": "8e5c2da581234abc",
"RuleID": "33aa8a8a948b48b28d40450c5fb92fba",
"Source": "firewallmanaged"
}