# Custom WAF Rules # Rule IDs 100000-199999 are reserved for custom rules # # NOTE: these directives are read by Coraza's seclang parser, which processes # backslash escapes in double-quoted strings. Use a single backslash (\.) to # escape a regex metacharacter -- a double backslash (\\.) reaches the regex # engine as "literal backslash followed by any char" and will never match. # Block requests where the Host header is an IP address (not a valid hostname) SecRule REQUEST_HEADERS:Host "^[\d.:]+$" "id:100001,phase:1,deny,status:403,log,msg:'Blocked request with IP-based Host header'" # Block requests with no Host header SecRule &REQUEST_HEADERS:Host "@eq 0" "id:100002,phase:1,deny,status:403,log,msg:'Blocked request with missing Host header'" # Block known bad user agents SecRule REQUEST_HEADERS:User-Agent "(?i)(badbot|nikto|sqlmap|nmap|masscan|zgrab)" "id:100003,phase:1,deny,status:403,log,msg:'Blocked malicious user agent'" # Block access to sensitive paths SecRule REQUEST_URI "(?i)/(\.env|\.git|\.svn|\.hg|wp-admin|wp-login|phpinfo|phpmyadmin|admin\.php|xmlrpc\.php)" "id:100004,phase:1,deny,status:403,log,msg:'Blocked access to sensitive path'" # Block excessively large request bodies (10MB) SecRule REQUEST_BODY_LENGTH "@gt 10485760" "id:100005,phase:2,deny,status:413,log,msg:'Request body too large'" # Block requests with empty User-Agent SecRule &REQUEST_HEADERS:User-Agent "@eq 0" "id:100006,phase:1,deny,status:403,log,msg:'Blocked request with missing User-Agent'"