About

A Web Application Firewall (WAF) HTTP filter plugin that provides layer 7 security for web applications using the Coraza WAF engine.

Features

This plugin provides comprehensive web application security:

  • OWASP CRS (Core Rule Set): Built-in protection against common web attacks
  • Request inspection: Analyzes HTTP requests for malicious patterns and anomalies
  • Response inspection: Examines HTTP responses to prevent data leakage
  • Flexible rule engine: Supports custom security rules and policies
  • Multiple operation modes: Detection-only or active blocking modes
  • Detailed logging: Comprehensive audit logging of security events

Security Rules

The WAF comes with support for OWASP CRS, formerly known as ModSecurity Core Rule Set (CRS), as well as some recommended configurations and allows custom rule configuration for specific security requirements. It is recommended to review the provided configuration files before deploying, to ensure they align with the target environment and the expected security posture. To use the bundled rules, you can include them with the Coraza Include directives as shown in this example:

{
  "directives": [
    "Include @coraza.conf",
    "Include @crs-setup.conf",
    "Include @owasp_crs/*.conf"
  ]
}

Available special names are:

Name Aliases Description
@coraza.conf-recommended Coraza upstream configuration file example
@coraza.conf @recommended.conf, @recommended-conf Coraza configuration file tailored for Coraza dynamic module implementation
@crs-setup.conf.example CRS upstream configuration file example
@crs-setup.conf @crs-setup-conf CRS configuration file tailored for Coraza dynamic module implementation
@owasp_crs/ CRS rules directory

Note: Aliases are provided for backward compatibility, but are deprecated and may be removed in future releases. It is recommended to use the primary names for new configurations.

To create custom rules, refer to the SecLang reference docs.

Mode

The optional mode setting controls which parts of the HTTP exchange are evaluated by the WAF. Use the narrowest mode that matches your policy to avoid unnecessary processing.

  • REQUEST_ONLY (default): Inspect request headers, body, and trailers only. This is the best choice for typical OWASP CRS deployments that focus on inbound attack detection.
  • RESPONSE_ONLY: Inspect response headers, body, and trailers only. Use this when you only need outbound inspection, such as detecting sensitive data in responses.
  • FULL: Inspect both request and response phases. Use this when your rules need visibility into both directions of traffic.
{
  "mode": "FULL",
  "directives": [
    "Include @coraza.conf",
    "Include @crs-setup.conf",
    "Include @owasp_crs/*.conf"
  ]
}

Note: mode only decides which request and response phases are passed to Coraza. It does not enable body access by itself. For example, FULL allows response-phase evaluation, but response body inspection still requires directives such as SecResponseBodyAccess On.

Metadata

The plugin emits the following filter dynamic metadata when requests are blocked by the WAF:

Namespace Key Description
io.builtonenvoy.waf block_phase Phase in which the requests has been blocked. See the execution flow for details on the possible values.
io.builtonenvoy.waf block_rule ID of the rule that triggered the block.

Metrics

The extension exposes the following metrics:

Metric Tags Type Description
waf_tx_total - Counter Total amount of transactions processed by the WAF.
waf_tx_blocked authority, phase, rule_id Counter Total amount of transactions blocked by the WAF. The rule_id will not be set if the request is not blocked by a concrete rule but by a WAF internal error.

Per Route Configuration

The extension supports per-route configuration, allowing you to specify different WAF rules and policies for different routes in your application. This is useful for tailoring security measures to specific endpoints or services.

The per-route configuration share the same format as the extension configuration and see Envoy's Dynamic Per Route Configuration for more details on how to set it up.

Usage Examples

SQL Injection Protection

The following example demonstrates how to run the WAF plugin with recommended OWASP CRS rules and test SQL injection protection by sending a malicious payload that should be blocked by the WAF.

By default WAF is configured in DetectionOnly mode, which means it will only log detected attacks without blocking them. To enable active blocking, this example sets SecRuleEngine On in the configuration. It also sets SecResponseBodyAccess Off to disable response body inspection as it's not needed for the example.

# Start WAF with recommended OWASP CRS rules and enforcement enabled
boe run --extension coraza-waf --config '
  {
    "directives": [
      "Include @coraza.conf",
      "SecRuleEngine On",
      "SecResponseBodyAccess Off",
      "Include @crs-setup.conf",
      "Include @owasp_crs/*.conf"
    ]
  }'

# Try sending a SQL injection payload and see the request rejected
curl -v http://localhost:10000/post -X POST --data "1%27%20ORDER%20BY%203--%2B"

< HTTP/1.1 403 Forbidden
< content-length: 22
< content-type: text/plain
< date: Thu, 12 Feb 2026 10:28:16 GMT
< server: envoy
<

CRS plugin from local filesystem

The following example demonstrates how to load a CRS plugin from the local filesystem and run the WAF plugin with recommended OWASP CRS rules.

It first downloads the WordPress rule exclusions plugin to a local file, enables blocking with SecRuleEngine On, and includes the plugin using Include /tmp/wordpress-plugin.conf. The same SQL injection payload that would normally be blocked is no longer blocked because the plugin excludes this specific attack vector.

# Retrieve the file
curl https://raw.githubusercontent.com/coreruleset/wordpress-rule-exclusions-plugin/refs/heads/master/plugins/wordpress-rule-exclusions-before.conf -o /tmp/wordpress-plugin-before.conf

# Start WAF with recommended OWASP CRS rules, enforcement enabled, and loading the plugin file
boe run --extension coraza-waf --config '
  {
    "directives": [
      "Include @coraza.conf",
      "SecRuleEngine On",
      "SecResponseBodyAccess Off",
      "Include @crs-setup.conf",
      "Include /tmp/wordpress-plugin-before.conf",
      "Include @owasp_crs/*.conf"
    ]
  }'

# Try sending a SQL injection payload and see the request rejected
curl -v "http://localhost:10000/wp-json/wp/v2/posts/1" -X POST -H "Content-Type: application/json" --data '{"content": "SELECT * FROM users WHERE id=1"}'

# The request is no longer blocked by the WAF as the rules in the plugin file are excluding the specific attack vector from being detected
< HTTP/1.1 404 Not Found
< date: Wed, 01 Apr 2026 13:10:33 GMT
< content-type: text/html
< content-length: 233
< server: envoy
...