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
Tests:
- Name: Likely Human
ExpectedResult: false
Log:
{
"BotScore": 99,
"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",
}
- Name: Likely Automated
ExpectedResult: true
Log:
{
"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",
}
# ------ paired body: cloudflare_httpreq_bot_high_volume.py ------
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)