Docs
Plugin HubOverview

chaitin-waf

The chaitin-waf plugin integrates with the Chaitin WAF (SafeLine) service to provide advanced detection and prevention of web-based threats, enhancing application security and protecting sensitive user data.

Chaitin WAF Block ModeBackendServiceChaitin WAFAPISIXClientBackendServiceChaitin WAFAPISIXClientopt[log_resp is enabled]alt[Request is legitimate][Request is malicious]Send API requestForward request for security checkReturn approvalForward requestReturn responseReturn responseReport the responseReturn denialReturn 403 ForbiddenChaitin WAF Block Mode
Chaitin WAF Block ModeBackendServiceChaitin WAFAPISIXClientBackendServiceChaitin WAFAPISIXClientopt[log_resp is enabled]alt[Request is legitimate][Request is malicious]Send API requestForward request for security checkReturn approvalForward requestReturn responseReturn responseReport the responseReturn denialReturn 403 ForbiddenChaitin WAF Block Mode

Response Headers

The plugin can add the following response headers, depending on the configuration of append_waf_resp_header and append_waf_debug_header:

HeaderDescription
X-APISIX-CHAITIN-WAFIndicates whether APISIX forwarded the request to the WAF server.
• yes: Request was forwarded to the WAF server.
• no: Request was not forwarded to the WAF server.
• unhealthy: Request matches the configured rules, but no WAF service is available.
• err: An error occurred during plugin execution. The X-APISIX-CHAITIN-WAF-ERROR header is also included with details.
• waf-err: Error while interacting with the WAF server. The X-APISIX-CHAITIN-WAF-ERROR header is also included with details.
• timeout: Request to the WAF server timed out.
X-APISIX-CHAITIN-WAF-TIMERound-trip time (RTT) in milliseconds for the request to the Chaitin WAF server, including both network latency and WAF server processing.
X-APISIX-CHAITIN-WAF-STATUSStatus code returned to APISIX by the WAF server.
X-APISIX-CHAITIN-WAF-ACTIONAction returned to APISIX by the WAF server.
• pass: Request was allowed by the WAF service.
• reject: Request was blocked by the WAF service.
X-APISIX-CHAITIN-WAF-ERRORDebug header. Contains WAF error message.
X-APISIX-CHAITIN-WAF-SERVERDebug header. Indicates which WAF server was selected.

Report Responses to WAF

Response reporting was introduced in API7 Enterprise 3.9.20 and 3.10.7, and in APISIX 3.19.0. It lets the WAF service observe the response status, headers, and a bounded body sample after the gateway serves the response. It does not block or modify that response.

Enable reporting in the plugin's config object on a route, or in the metadata config object to set the default for all routes:

{
  "log_resp": true,
  "resp_body_size": 4
}

The example keeps the default body limit of 4 KiB; reporting is disabled by default. Set the body limit to 0 to report only status and headers. Response content types in the built-in ignored list or extra_ignored_content_types are not reported at all.

The report is sent asynchronously, but collecting the sample still uses gateway memory during the response. Account for concurrent responses when increasing the limit, avoid sending sensitive response data unnecessarily, and monitor response-reporting errors in the gateway log.

Examples

The examples below demonstrate how you can configure chaitin-waf plugin for different scenarios.

Before proceeding, make sure you have installed Chaitin WAF (SafeLine).

Block Malicious Requests on a Route

The following example demonstrates how to integrate with Chaitin WAF to protect traffic on a route, rejecting malicious requests immediately.

Configure the Chaitin WAF connection details using plugin metadata (opens in Apache APISIX docs) (update the address accordingly):

curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/chaitin-waf" -X PUT \
  -H "X-API-KEY: ${ADMIN_API_KEY}" \
  -d '{
    "nodes": [
      {
        "host": "172.22.222.5",
        "port": 8000
      }
    ]
  }'

Create a route and enable chaitin-waf on the route to block requests identified to be malicious:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${ADMIN_API_KEY}" \
  -d '{
    "id": "chaitin-waf-route",
    "uri": "/anything",
    "plugins": {
      "chaitin-waf": {
        "mode": "block",
        "append_waf_resp_header": true,
        "append_waf_debug_header": true
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

❶ Set mode to block to block requests identified to be malicious.

❷ Set append_waf_resp_header to true to include WAF-related standard response headers.

❸ Set append_waf_debug_header to true to include WAF-related debugging response headers.

Send a standard request to the route:

curl -i "http://127.0.0.1:9080/anything"

You should receive an HTTP/1.1 200 OK response.

Send a request with SQL injection to the route:

curl -i "http://127.0.0.1:9080/anything" -d 'a=1 and 1=1'

You should see an HTTP/1.1 403 Forbidden response similar to the following:

...
X-APISIX-CHAITIN-WAF-STATUS: 403
X-APISIX-CHAITIN-WAF-ACTION: reject
X-APISIX-CHAITIN-WAF-SERVER: 172.22.222.5
X-APISIX-CHAITIN-WAF: yes
X-APISIX-CHAITIN-WAF-TIME: 3
...

{"code": 403, "success":false, "message": "blocked by Chaitin SafeLine Web Application Firewall", "event_id": "276be6457d8447a4bf1f792501dfba6c"}

Monitor Requests for Malicious Intent

This example shows how to integrate with Chaitin WAF to monitor all routes with chaitin-waf without rejection, and to reject potentially malicious requests on a specific route.

Configure the Chaitin WAF connection details using plugin metadata (opens in Apache APISIX docs) (update the address accordingly) and configure the mode:

curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/chaitin-waf" -X PUT \
  -H "X-API-KEY: ${ADMIN_API_KEY}" \
  -d '{
    "nodes": [
      {
        "host": "172.22.222.5",
        "port": 8000
      }
    ],
    "mode": "monitor"
  }'

❶ Set mode to monitor in the plugin metadata. This applies to all chaitin-waf plugin instances if mode is not specified on a route.

Create a route and enable chaitin-waf without any configuration on the route:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${ADMIN_API_KEY}" \
  -d '{
    "id": "chaitin-waf-route",
    "uri": "/anything",
    "plugins": {
      "chaitin-waf": {}
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

Send a standard request to the route:

curl -i "http://127.0.0.1:9080/anything"

You should receive an HTTP/1.1 200 OK response.

Send a request with SQL injection to the route:

curl -i "http://127.0.0.1:9080/anything" -d 'a=1 and 1=1'

You should also receive an HTTP/1.1 200 OK response as the request is not blocked in the monitor mode, but observe the following in the log entry:

2025/09/09 11:44:08 [warn] 115#115: *31683 [lua] chaitin-waf.lua:385: do_access(): chaitin-waf monitor mode: request would have been rejected, event_id: 49bed20603e242f9be5ba6f1744bba4b, client: 172.20.0.1, server: _, request: "POST /anything HTTP/1.1", host: "127.0.0.1:9080"

If you explicitly configure the mode on a route, it will take precedence over the configuration in the plugin metadata. For instance, if you create a route like this:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${ADMIN_API_KEY}" \
  -d '{
    "id": "chaitin-waf-route",
    "uri": "/anything",
    "plugins": {
      "chaitin-waf": {
        "mode": "block"
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

Send a standard request to the route:

curl -i "http://127.0.0.1:9080/anything"

You should receive an HTTP/1.1 200 OK response.

Send a request with SQL injection to the route:

curl -i "http://127.0.0.1:9080/anything" -d 'a=1 and 1=1'

You should see an HTTP/1.1 403 Forbidden response similar to the following:

...
X-APISIX-CHAITIN-WAF-STATUS: 403
X-APISIX-CHAITIN-WAF-ACTION: reject
X-APISIX-CHAITIN-WAF: yes
X-APISIX-CHAITIN-WAF-TIME: 3
...

{"code": 403, "success":false, "message": "blocked by Chaitin SafeLine Web Application Firewall", "event_id": "c3eb25eaa7ae4c0d82eb8ceebf3600d0"}