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

The current version of the CRS is 3.0.2.

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.

Rule Format

ModSecurity rules are called SecRules. The format for for a SecRule is:


The variables can include specific headers, the request body, etc. The operator will check against the variables. This can be regex or a simple equals. Transformations and actions include id number, phase, hashing, block a request, or deny a request. Transformations are done before the operator comparison, while actions are done if the comparison was successful. Each rule must contain an ID number. An example of a simple rule to check if a request URL is equal to index.php is:

SecRule REQUEST_URI "@streq /index.php" "id:1,phase:1,t:lowercase,deny"

More information about SecRule formats can be found here and more information about what a SecRule is made up of can be found here. Some basic rules on creating a SecRule are:

  1. Every SecRule must have a VARIABLE.
  2. Every SecRule must have an OPERATOR, if none is listed @rx is implied.
  3. Every SecRule must have an ACTION. The only required action is id, however, several actions are implied by SecDefaultAction (default phase:2, log, auditlog, pass).
  4. Every SecRule must have a phase, this determine when the rule is run. If no phase is included the default is 2.
  5. Every SecRule must have a disruptive ACTION. This is an action that describes what should happen when a rule contained a successful comparison. If no disruptive action is included the default is pass.
  6. Transformations are optional but should be used to prevent your rule from being bypassed.

Checking Rules are Valid

ModSecurity provides a tool, modsec-rules-check, to determine the validity of rules and configuration files. There are a few different ways to use this program.

Checking One Configuration File

modsec-rules-check /etc/varnish/modsec/owasp-crs/rules/REQUEST-901-INITIALIZATION.conf 
 : /etc/varnish/modsec/owasp-crs/rules/REQUEST-901-INITIALIZATION.conf  --  Loaded 40 rules.
Test ok.

Checking an Entire Folder

modsec-rules-check /etc/varnish/modsec/owasp-crs/rules/*.conf
 : /etc/varnish/modsec/owasp-crs/rules/crs-setup.conf  --  Loaded 1 rules.
 : /etc/varnish/modsec/owasp-crs/rules/REQUEST-901-INITIALIZATION.conf  --  Loaded 40 rules.

. . . 

Test ok.

Checking Recomended Configuration File

This is different than the previous two examples because it contains multiple configuration files under in one file.

modsec-rules-check /etc/varnish/modsec/waf.conf
 : reccomended_file  --  Loaded 819 rules.
Test ok.

Disruptive Methodology

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. The former default method is called Traditional. Traditional method will block the request at the first successful SecRule. For example:

SecDefaultAction "phase:2,deny,status:403,log"

While this method is straightforward and performs better due to less rules checked, there are more disadvantages to it. Some disadvantages are, low severity rules might not trigger a block, or multiple low severity rules will combine for a larger issue that won’t be blocked. Additionally, not all successful rules will be checked and logged, creating a possible blind spot, and not all sites require the same harsh rule checks.

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 scores, like sql_injection_score, that are used in the CRS are set in the file /etc/varnish/modsec/owas-crs/rules/REQUEST-901-INITIALIZATION.conf in rule 901200.

Security 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. To gain a functioning site, many exclusion rules will most likely need to be added. The default paranoia level is 1. Rules with a paranoia level 2 or higher will log that in the audit log. The paranoia level is set in the file /etc/varnish/modsec/owas-crs/rules/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.