waf_debug_log

The built-in waf_debug_log subroutine is executed after a rule is matched by the Web Application Firewall and is intended to be used to capture data about a WAF event.

This subroutine is always appended to a service VCL by Fastly. It cannot be edited using custom VCL or VCL snippets. To use waf_debug_log to capture WAF data:

  1. Create a logging endpoint.
  2. Set the endpoint's placement property to "waf_debug".
  3. Set a format string that includes WAF variables.

WAF variables

WAF-related variables are typically scoped to vcl_miss and vcl_pass. The waf_debug_logvariable does not have a dedicated scope because it is invoked from code that runs as part of the vcl_miss or vcl_pass subroutine.

The following variables track the cumulative scores accumulated by all the scoring rules that have been executed so far, including the one that triggered the current call to waf_debug_log:

  • waf.anomaly_score
  • waf.xss_score
  • waf.sql_injection_score
  • waf.rfi_score
  • waf.rce_score
  • waf.php_injection_score
  • waf.session_fixation_score
  • waf.lfi_score
  • waf.http_violation_score

waf.anomaly_score is the total score of all rules that have matched so far, while the other score variables count only the scores of rules in their category. Between successive invocations of waf_debug_log, these numbers will increase by the amount contributed by the most recently matched rule. waf.failures will also be incremented each time the execution of a rule fails (and therefore may also change between successive calls to waf_debug_log).

This second set of WAF variables are also set by Fastly when a WAF rule matches, but describe only the rule that was most recently matched:

  • waf.severity
  • waf.rule_id
  • waf.message
  • waf.logdata

These variables hold the data that is usually most valuable to log using a WAF logging endpoint.

Finally, these WAF-related variables are set or modified only once during the execution of the WAF:

  • waf.executed
  • waf.blocked
  • waf.passed
  • waf.logged

Since these variables are not specific to particular rules, if you intend to log them it is more useful to do so only once per request, in vcl_log, by setting the placement property of a log endpoint to "vcl_log".

Log format example

The following log format string will capture the most common per-rule WAF variables in a JSON format, which is suitable for many logging providers.

{"type":"waf","request_id":"%{req.http.fastly-soc-x-request-id}V","rule_id":"%{waf.rule_id}V","severity":"%{waf.severity}V","anomaly_score":"%{waf.anomaly_score}V","logdata":"%{json.escape(waf.logdata)}V","waf_message":"%{json.escape(waf.message)}V"}

Remember that when using the Fastly API to set the format property of a log endpoint, you will need to escape the value as either a JSON string, or a URL encoded string, depending on the content-type you use for the API request.