Microservice APIs are exposed to common web attacks such as SQL injection (SQLi), cross-site scripting (XSS), local and remote file inclusion (LFI/RFI), and remote code execution (RCE). The WAF plug-in adds a ModSecurity-based rules engine at the gateway level to inspect incoming HTTP requests and block malicious traffic. It supports the OWASP ModSecurity Core Rule Set (CRS) v3.3.2 for out-of-the-box protection without writing custom rules.
Enable the CRS with a single field:
useCRS: trueThe WAF plug-in uses static, open-source ModSecurity rules. It does not auto-update to address emerging threats. For real-time threat detection and managed rule updates, enable WAF protection for your MSE instance. For more information, see Add an MSE instance to WAF.
Plug-in type
Security protection plug-in.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
useCRS | bool | No | false | Enables the OWASP CRS. When set to true, the plug-in loads the CRS v3.3.2 rule set and blocks requests that match any rule. |
secRules | array of string | No | - | Custom rules written in ModSecurity SecRule syntax. Use this field to add your own rules, override CRS behavior, or switch the engine mode. |
ModSecurity processing phases
Each request passes through five ModSecurity processing phases. The phase parameter in a SecRule determines when the rule runs:
| Phase | Inspects | Typical use |
|---|---|---|
| 1 | Request headers, URI, method | URI-based access control, IP blocking |
| 2 | Request body | POST payload inspection, file upload checks |
| 3 | Response headers | Response header validation |
| 4 | Response body | Sensitive data leak detection |
| 5 | Logging | Audit logging (no blocking) |
When a rule matches, ModSecurity runs the action defined in that rule (deny, pass, log, and so on). If the action is deny, the plug-in returns an HTTP 403 response to the client.
Configuration examples
Enable the default CRS rules
Block requests that match any CRS rule:
useCRS: trueAll requests are evaluated against the CRS rule set. Matching requests receive an HTTP 403 response.
Use detection-only mode
Evaluate requests against CRS rules and log matches without blocking traffic. This mode helps you identify false positives before enforcing rules in production.
useCRS: true
secRules:
- "SecRuleEngine DetectionOnly"Add custom rules
Add custom SecRule directives alongside the CRS rule set. The following example blocks requests to /admin and requests that contain maliciouspayload in the body:
useCRS: true
secRules:
- "SecRule REQUEST_URI \"@streq /admin\" \"id:101,phase:1,t:lowercase,deny\""
- "SecRule REQUEST_BODY \"@rx maliciouspayload\" \"id:102,phase:2,t:lowercase,deny\""Rule breakdown:
| Rule ID | Phase | Match condition | Action |
|---|---|---|---|
| 101 | 1 (request headers) | URI equals /admin (case-insensitive) | Deny |
| 102 | 2 (request body) | Body matches regex maliciouspayload (case-insensitive) | Deny |
Blocked requests:
The following requests return HTTP 403:
# Blocked by rule 101 -- URI matches /admin
curl http://example.com/admin
# Blocked by rule 102 -- body matches maliciouspayload
curl http://example.com -d "maliciouspayload"Apply rules to a specific route or domain name
Define global rules at the plug-in level, then override specific behaviors per route or domain name. The following example uses three configuration layers:
Global plug-in configuration (applies to all routes by default):
useCRS: true
secRules:
- "SecRule REQUEST_URI \"@streq /admin\" \"id:101,phase:1,t:lowercase,deny\""
- "SecRule REQUEST_BODY \"@rx maliciouspayload\" \"id:102,phase:2,t:lowercase,deny\""Route-level override for route route-1 (deny rule 102):
secRules:
- "SecAction \"id:102,phase:1,deny\""Domain-level override for *.example.com and test.com (pass rule 102):
secRules:
- "SecAction \"id:102,phase:1,pass\""route-1refers to a named route defined in the gateway. When a client request matches this route, the route-level rules take effect.*.example.comandtest.comare domain-matching patterns. When a client request matches one of these domains, the domain-level rules take effect.Rules take effect in sequence. If the first rule is matched, subsequent rules are ignored.
Best practices
Start with detection-only mode
Before enforcing rules in production, run the plug-in in detection-only mode to observe matched rules without blocking traffic. Review the logs for false positives, then switch to enforcement mode with SecRuleEngine On.
Assign unique IDs to custom rules
Every custom SecRule must have a unique numeric id to avoid conflicts with CRS rule IDs.
Apply targeted rules to routes
Instead of writing broad global rules, scope rules to specific routes or domains. This minimizes the risk of unintended blocks and simplifies troubleshooting.
What's next
Add an MSE instance to WAF -- Enable managed WAF protection with real-time threat intelligence and auto-updating rules.
CRS v3.3.2 on GitHub -- Browse the default OWASP CRS rules.
ModSecurity reference -- SecRule syntax documentation.