WAF (Coraza)
Overview
The WAF uses Coraza SPOA via HAProxy’s SPOE filter mechanism. It provides OWASP CRS protection, custom SecRules, conditional exceptions, rule version snapshots, SIEM forwarding, and remote rule set management — all managed from the coreX Manager UI.
Rule Set Types
coreX Manager supports three types of WAF rule sets:
CRS (OWASP CRS)
The OWASP Core Rule Set is bundled in the coraza-spoa image. CRS provides broad protection against common web attacks (SQL injection, XSS, RCE, LFI/RFI, etc.) using anomaly scoring.
Custom
Custom rule sets contain only sec_rules — no includes, no CRS. Use these for application-specific rules that don’t fit the CRS model.
Remote
Remote rule sets download .conf files from a URL with SHA256 verification and optional auto-update on a configurable interval. This is useful for subscribing to third-party rule feeds.
WAF Rules
WAF rules are created per listener. Each rule specifies:
| Property | Description |
|---|---|
| Name | Display name |
| Listener | Which listener to protect |
| Rule set | CRS, Custom, or Remote |
| Anomaly threshold | Score at which the request is blocked |
| Action | What to do when the threshold is exceeded |
| Enabled | Toggle without deleting |
Actions
| Action | Description |
|---|---|
| block | Return 403 |
| allow | Permit the request |
| log | Log but allow |
| challenge | Present a CAPTCHA challenge |
| captcha | Integrated CAPTCHA challenge |
Exceptions
Conditional exceptions let you skip specific CRS rules for specific conditions. For example, skip rule 942100 (SQL injection detection) for a specific endpoint that legitimately accepts SQL-like input.
Each exception has:
- Rule ID — the CRS rule to skip
- Condition — when to skip (e.g.
http.request.uri.path matches "^/api/search") - Listener scoping
Rule Version Snapshots
coreX Manager can save and restore the full configuration of a single WAF rule. This is useful for:
- Auditing changes over time
- Rolling back a bad configuration change
- Comparing before/after states
Auto-pruning keeps the N most recent snapshots per rule (configurable).
CRS Downloader
The CRS downloader fetches official OWASP CRS releases from GitHub. Features:
- Download specific CRS versions
- Rollback to previous versions
- View release notes
- Automatic update checks
Each CRS version is stored separately. You can switch between versions without re-downloading. The active version is the one referenced by WAF rules that use the CRS rule set type.
Remote Rule Set Downloader
For remote rule sets:
- Download
.conffiles from a URL - Verify SHA256 checksum
- Auto-update on a configurable interval
- Manual refresh button for immediate updates
SIEM Forwarder
The SIEM forwarder sends WAF events to external SIEM systems:
| Destination | Description |
|---|---|
| Webhook | HTTP POST to a URL |
| Syslog | RFC 5424 syslog messages |
| Elasticsearch | Direct Elasticsearch API indexing |
Per-rule SIEM integration allows linking specific WAF rules to specific SIEM destinations, so critical rules can be forwarded to a high-priority destination while lower-severity rules go to a general log.
WAF Logs
The WAF Logs page shows expandable rows with full Coraza event details:
- Rule ID, message, severity
- Client IP, URI, method
- Matched data / variables
- Action taken
- Timestamp
Inline search lets you filter by any field.
WAF Metrics
WAF events are sampled into the database for dashboard breakdowns:
- Breakdowns: action, rule ID, severity, message
- Stacked bar chart over time
- Totals table with counts per category
- Configurable time range
Blocking Behavior
SecRuleEngine On must be set after all includes. If it appears before includes, the engine may not pick up the included rules correctly. coreX Manager handles this automatically in generated configs.
Do not duplicate SecDefaultAction. CRS defines its own default action. Adding a conflicting default action can cause unexpected behavior. coreX Manager validates this before apply.
Custom Error Pages
WAF can serve custom error pages for 403 (blocked) and 500 (internal error) responses. Template variables available:
| Variable | Description |
|---|---|
{{ request_id }} | HAProxy unique request ID |
{{ waf_unique_id }} | Coraza transaction ID |
Step-by-Step: Enable WAF with CRS
- Navigate to Security > WAF
- If no CRS is downloaded, click Download CRS (latest version)
- Click Add WAF Rule
- Name:
protect-web - Select your listener
- Rule set: CRS
- Anomaly threshold:
5(start conservative) - Action: block
- Click Save
- Click Apply Changes
When deploying WAF for the first time, set the action to log and monitor the WAF Logs page for false positives. Once you’re confident, switch to block. Add exceptions for any legitimate traffic that triggers rules.
Step-by-Step: Add an Exception
- Navigate to Security > WAF > Exceptions
- Click Add Exception
- Rule ID:
942100(SQL injection detection) - Condition:
http.request.uri.path matches "^/api/search" - Listener: select the relevant listener
- Save and Apply
Step-by-Step: Configure SIEM Forwarding
- Navigate to Security > WAF > SIEM
- Click Add Destination
- Type: Webhook
- URL:
https://siem.example.com/api/waf-events - Save
- Link a WAF rule to this destination from the rule’s SIEM settings
Verification
-
Test with a malicious request:
curl -k "https://localhost/?id=1' OR '1'='1"Expect a 403 (or log entry if in log-only mode).
-
Check WAF Logs:
- Navigate to Observability > WAF Logs
- Verify the event appears with rule ID and details
-
Check WAF Metrics:
- Navigate to Observability > Metrics > WAF
- Verify events appear in the breakdown chart
-
Test with a benign request:
curl -k https://localhost/Expect a normal 200 response.
Next Steps
- Security Rules — Layer access control on top of WAF
- CAPTCHA — Configure challenge providers for WAF challenge actions
- Metrics & Logging — Monitor WAF events and metrics