Description
Reporting a false negative: CRS (tested at PL1 and PL2) does not detect a
distributed botnet DDoS campaign currently active against WooCommerce
stores. The campaign uses GET-based cart and facet parameter flooding to
saturate PHP-FPM pools via forced uncached WP_Query execution.
Two distinct request patterns are used in rotation:
Pattern A — GET add-to-cart flood: bot sends GET requests with
add-to-cart=<product_id> in the query string. Legitimate WooCommerce
themes use POST/AJAX for cart operations; GET add-to-cart at volume is
essentially always malicious.
Pattern B — Facet parameter permutation flood: bot enumerates
combinations of facet parameters (product_count, product_orderby,
product_order, product_view, orderby, per_page, min_price,
max_price, filter_*) on WooCommerce taxonomy and listing paths
(/product-tag/, /product-category/, /category/, /shop/,
/products/, /collections/, /tag/). Each permutation defeats caching
and forces a fresh WP_Query execution.
Botnet characteristics observed:
- Thousands of unique residential source IPs per wave
- 1–3 requests per source IP (defeats per-IP rate limiting)
- Spoofed Chrome/Safari/Edge User-Agents
- No session cookies, no Referer on most requests
- Targets appear to be discovered by enumeration of shared hosting IPs
(two separate sites on the same server hit in sequence weeks apart)
Observed impact on an unprotected WooCommerce site with a 10-worker
PHP-FPM pool: full saturation within approximately 30 seconds; cascading
504 Gateway Timeout errors; neighbouring vhosts starved via Apache
MaxRequestWorkers exhaustion; load average rising from baseline 2 to 17+;
sustained outage until mitigation deployed.
After deploying custom rules (shown below) on ModSec 2.9 running CRS at
PL1, over 95% of attack requests were blocked at phase:1. Load recovered
within minutes, with zero reported false positives on legitimate customer
traffic during initial monitoring.
How to reproduce the misbehavior (-> curl call)
Each of the following requests represents in-the-wild attack traffic that
passes CRS PL1 and PL2 without triggering a block:
# Pattern A — GET add-to-cart
curl -i "https://target.example/products/item-slug/?add-to-cart=1234"
curl -i "https://target.example/category/gloves/?add-to-cart=2614&product_count=60"
curl -i "https://target.example/product-tag/safety/?add-to-cart=3371&product_order=desc"
# Pattern B — facet permutation on taxonomy paths
curl -i "https://target.example/product-tag/safety/?product_count=40&product_orderby=name"
curl -i "https://target.example/category/gloves/?product_view=list&product_order=desc"
curl -i "https://target.example/shop/?orderby=price&per_page=60"
curl -i "https://target.example/product-category/footwear/?filter_size=large&min_price=100"
# Pattern C (related variant) — GET to wc-ajax endpoints
curl -i "https://target.example/?wc-ajax=add_to_cart"
curl -i "https://target.example/?wc-ajax=get_refreshed_fragments"
Expected behaviour: CRS should flag these as suspicious GET abuse against
WooCommerce endpoints, given that all of these operations are documented
as POST/AJAX in WooCommerce core.
Actual behaviour: all requests pass through CRS without matching any
existing rule.
Logs
Anonymised access log samples from a real attack wave (IPs scrubbed,
domain replaced, timestamps preserved for rate indication):
X.X.X.X - - [23/Apr/2026:14:02:17 +0200] "GET /product-tag/construction/?product_count=40&product_view=list HTTP/1.0" 504 3781 "https://target.example/product-tag/construction/?product_count=40" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
X.X.X.X - - [23/Apr/2026:14:02:17 +0200] "GET /category/gloves/?add-to-cart=2654&product_count=60&product_order=asc&product_orderby=date&product_view=list HTTP/1.0" 504 3781 "https://target.example/category/gloves/?add-to-cart=2654&product_count=60&product_orderby=date&product_view=list" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"
X.X.X.X - - [23/Apr/2026:14:02:18 +0200] "GET /product-tag/ppe/?add-to-cart=3992&product_count=60&product_orderby=popularity HTTP/1.0" 504 3781 "https://target.example/product-tag/ppe/?add-to-cart=3992&product_count=60&product_orderby=price" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0"
X.X.X.X - - [23/Apr/2026:14:02:18 +0200] "GET /product-tag/safety/?add-to-cart=2881&product_count=20&product_orderby=price&product_view=grid HTTP/1.0" 504 3781 "https://target.example/product-tag/safety/?add-to-cart=2881&product_count=60&product_orderby=price&product_view=grid" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"
Full sanitised audit log export available on request — happy to share
privately with maintainers if useful.
Proposed detection
Phase 1 chain rules. Have been running in production for the past few
hours with no observed false positives:
SecRule REQUEST_METHOD "@streq GET" \
"id:9xxxxx,phase:1,chain,block,t:none, \
msg:'WooCommerce: Suspicious GET add-to-cart request', \
tag:'application-multi',tag:'platform-woocommerce', \
tag:'attack-dos',severity:'CRITICAL'"
SecRule QUERY_STRING "@rx (?:^|&)add-to-cart=" ""
SecRule REQUEST_METHOD "@streq GET" \
"id:9xxxxx,phase:1,chain,block,t:none, \
msg:'WooCommerce: Facet parameter flood on taxonomy path', \
tag:'application-multi',tag:'platform-woocommerce', \
tag:'attack-dos',severity:'CRITICAL'"
SecRule REQUEST_FILENAME \
"@rx ^/(product-tag|product-category|category|shop|products|collections|tag)/" "chain"
SecRule QUERY_STRING \
"@rx (?:^|&)(product_count|product_orderby|product_order|product_view|orderby|per_page|min_price|max_price|filter_[a-z_]+)=" ""
SecRule REQUEST_METHOD "@streq GET" \
"id:9xxxxx,phase:1,chain,block,t:none, \
msg:'WooCommerce: GET to wc-ajax cart endpoint', \
tag:'application-multi',tag:'platform-woocommerce', \
tag:'attack-dos',severity:'CRITICAL'"
SecRule QUERY_STRING \
"@rx (?:^|&)wc-ajax=(add_to_cart|get_refreshed_fragments|remove_from_cart|apply_coupon)" ""
Suggest placement in a new REQUEST-94x-APPLICATION-SPECIFIC-WOOCOMMERCE.conf
file, or in REQUEST-934-APPLICATION-ATTACK-GENERIC.conf. Could also be
gated behind an opt-in variable like tx.enforce_woocommerce_hardening
given that the target audience is specifically WooCommerce hosts.
Your Environment
- CRS version: 3.x (default paranoia level 1)
- Paranoia level setting: PL1 (also tested at PL2 — same result)
- ModSecurity version: 2.9
- Web Server and version: Apache httpd 2.4 with mod_proxy_fcgi to PHP-FPM
- Operating System and version: Ubuntu 24.04 LTS (Plesk-managed hosting)
Confirmation
[x] I have removed any personal data (email addresses, IP addresses,
passwords, domain names) from any logs posted.
Description
Reporting a false negative: CRS (tested at PL1 and PL2) does not detect a
distributed botnet DDoS campaign currently active against WooCommerce
stores. The campaign uses GET-based cart and facet parameter flooding to
saturate PHP-FPM pools via forced uncached WP_Query execution.
Two distinct request patterns are used in rotation:
Pattern A — GET add-to-cart flood: bot sends GET requests with
add-to-cart=<product_id>in the query string. Legitimate WooCommercethemes use POST/AJAX for cart operations; GET add-to-cart at volume is
essentially always malicious.
Pattern B — Facet parameter permutation flood: bot enumerates
combinations of facet parameters (
product_count,product_orderby,product_order,product_view,orderby,per_page,min_price,max_price,filter_*) on WooCommerce taxonomy and listing paths(
/product-tag/,/product-category/,/category/,/shop/,/products/,/collections/,/tag/). Each permutation defeats cachingand forces a fresh WP_Query execution.
Botnet characteristics observed:
(two separate sites on the same server hit in sequence weeks apart)
Observed impact on an unprotected WooCommerce site with a 10-worker
PHP-FPM pool: full saturation within approximately 30 seconds; cascading
504 Gateway Timeout errors; neighbouring vhosts starved via Apache
MaxRequestWorkers exhaustion; load average rising from baseline 2 to 17+;
sustained outage until mitigation deployed.
After deploying custom rules (shown below) on ModSec 2.9 running CRS at
PL1, over 95% of attack requests were blocked at phase:1. Load recovered
within minutes, with zero reported false positives on legitimate customer
traffic during initial monitoring.
How to reproduce the misbehavior (-> curl call)
Each of the following requests represents in-the-wild attack traffic that
passes CRS PL1 and PL2 without triggering a block:
Expected behaviour: CRS should flag these as suspicious GET abuse against
WooCommerce endpoints, given that all of these operations are documented
as POST/AJAX in WooCommerce core.
Actual behaviour: all requests pass through CRS without matching any
existing rule.
Logs
Anonymised access log samples from a real attack wave (IPs scrubbed,
domain replaced, timestamps preserved for rate indication):
Full sanitised audit log export available on request — happy to share
privately with maintainers if useful.
Proposed detection
Phase 1 chain rules. Have been running in production for the past few
hours with no observed false positives:
Suggest placement in a new
REQUEST-94x-APPLICATION-SPECIFIC-WOOCOMMERCE.conffile, or in
REQUEST-934-APPLICATION-ATTACK-GENERIC.conf. Could also begated behind an opt-in variable like
tx.enforce_woocommerce_hardeninggiven that the target audience is specifically WooCommerce hosts.
Your Environment
Confirmation
[x] I have removed any personal data (email addresses, IP addresses,
passwords, domain names) from any logs posted.