Varnish WAF


The Open Web Application Security Project (OWASP) is a community that produces information and tools in the field of web application security like the Core Rule Set (CRS). The CRS is a set of generic attack detection rules for use with ModSecurity. The CRS aims to protect web applications from a wide range of attacks, including the OWASP Top 10, with minimum false alerts. The Core Rule Set provides protection against many common attack categories including:

  • SQL Injection (SQLi)
  • Cross Site Scripting (XSS)
  • Local File Inclusion (LFI)
  • Remote File Inclusion (RFI)
  • Remote Code Execution (RCE)
  • PHP Code Injection
  • HTTP Protocol Violations
  • HTTPoxy
  • Shellshock
  • Session Fixation
  • Scanner Detection
  • Metadata/Error Leakages
  • Project Honey Pot Blacklist
  • GeoIP Country Blocking

File Breakdown

There are three types of important files included in this rule set: configuration, rule sets, and data files. The rule sets and data files are located in the rules folder while the configuration resides in the main directory. The list below will describe the file naming scheme and the purpose of each set of files.

  • crs-setup.conf is the main configuration file for the CRS. It gives the user a way to edit the default actions of the CRS.
  • 90X files are rule exclusions to combat false positives.
    • This section of files contains exclusions to common web applications like WordPress and Drupal.
  • 91X files detect malicious clients (scanners and bots).
  • 92X files detect protocol violations.
  • 93X and 94X files detect application attacks (SQLi, LFI, XSS, PHP, RFI, LFI).
  • 95X files detect data leaks.
  • *.data files hold information for the previous rules. For example will be used to scan the response body for SQL errors, to prevent data leakages.

Anomaly Scoring

A disruptive action occurs when a successful rule blocks or denies a request. As of ModSecurity V3, the default scoring method is called Anomaly Scoring. Anomaly Scoring is less harsh than Traditional disruptive methods. The goal of Anomaly Scoring is to reduce the number of false positives. To do this, there is a threshold that must be hit for a disruptive action to occur. Each successful SecRule will increment a counter rather than block automatically. This is done using the setvar action.


As shown above, the variable anomaly_score is incremented by critical_anomaly_score, a variable set in crs-setup.conf in rule 900110. Specific rules can be set to block a request once a specific anomaly score threshold has been broken. There are four default anomaly scoring levels:

  1. critical_anomaly_score, set to 5, is generated by application attack rules (93X and 94X files). This usually results in an automatic deny/block.
  2. error_anomaly_score, set to 4, is generated by outbound leakage rules (95X files). This usually results in an automatic deny/block.
  3. warning_anomaly_score, set to 3, is generated by malicious client rules (91X files).
  4. notice_anomaly_score, set to 2, is generated by protocol rules (92X files).

The two main anomaly score are inbound_anomaly_score_threshold and outbound_anomaly_score_threshold, set to 5 and 4 by default. These thresholds represent request threshold and response threshold. There are other thresholds used throughout the CRS. Some SecRules check just against the anomaly score, like the example above. Another example is sql_injection_score which scores the risk of SQLi related issues. Other thresholds are set in the file REQUEST-901-INITIALIZATION.conf in rule 901200.

Paranoia Level

Another way to combat false positives is the inclusion of a paranoia level. The paranoia level dictates how many rules should be considered. The higher the paranoia level, the more rules that are enabled, possibly creating false positives. The default paranoia level is 1. Rules with a paranoia level 2 or higher will log be logged in the audit log. The paranoia level is set in the file REQUEST-901-INITIALIZATION.conf in rule 900000. The paranoia levels are as follows:

  1. Most of the core rules are enabled. False positives are rare.
  2. Includes extra rules such as enabling regex based SQL and XSS injection. False positives are more likely.
  3. Includes more rules such as limits on special characters used. This is used in high security situations but with many false positives.
  4. Further restrict special characters. High amount of false positives are likely.

Tuning the Rule Set

Before going into production, it is best to see how Varnish WAF works with the current web application. There can be false positives blocking users where they should not be blocked and take up unnecessary compute resources. A method to scale down the amount of false positives is shown in the following steps:

  1. Make sure the SecRuleEngine and SecAuditEngine are set to on.
  2. In crs-setup.conf set the rule, 900110, containing the inbound and outbound anomaly thresholds to a very high number such as 1,000 to make sure all requests pass through (resulting in no little to no blocked requests).
  3. Go through the flow of the web application.
  4. Examine the audit log for false positives.
  5. Add rules producing false positives to RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf with SecRuleRemoveById NUMBER.
  6. If no false positives are present, lower the anomaly thresholds and repeat these steps starting from step 3 until the thresholds are back to their default values of 5 and 4.

O’Reilly has a tutorial about limiting the amount of false positives that follows similar logic as the one described above but with some useful grep based tools to further examine the amount of false positives. Furthermore, some other tools that will help you navigate your web application looking for vulnerabilities like those in the OWASP top 10, include OWASP’s Zed Attack Proxy Protocol, Zap, and Nikito. Both of these tools are open source projects that scan and attack web applications to help fill security holes. The usage of these tools are outside of the scope of this documentation.