About

This website implements a linter for the Cloudflare firewall rules. The filters can become quite complex, and logic errors can have major consequences, like blocking all traffic to a website. Check out the examples below to see what kind of detection logic is implemented.
You find the whole project on GitHub  jonasbb/cloudflare-rule-linter.

Examples

Click on the examples to see the lint results.
  • deprecated_field Check for usage of old field names and suggest the correct new values.
    ip.geoip.country eq "T1"
  • duplicate_list_entries Detect duplicate values in lists.
    ip.src in {1.0.0.0/8 1.1.0.0/16}
    http.request.uri.path in {"/foo" "/foo"}
  • empty_list Check for comparisons against empty lists, which are always false.
    ip.src in {}
  • header_case Checks for header names that are not all lowercase.
    any(http.request.headers["Authorization"][*] wildcard "Bearer *")
  • illogical_condition Detect illogical conditions, such as comparing the same field for equality multiple times in an AND expression, or for inequality multiple times in an OR expression.
    (http.host in { "example.com" }) and (http.host eq "example.org")
    not http.host eq "example.com" or http.host != "example.org"
  • invalid_list_name Check for invalid managed list names and optionally invalid custom list names.
    ip.src in $cf.bot
  • negated_comparison Detect comparisons that are negated and suggest using the opposite comparison operator instead.
    not http.host eq "example.com"
    not ip.src.asnum gt 1024
  • operator_style Enforce a consistent operator notation (english vs C-like).
    http.host == "abc" && http.host eq "def"
  • overly_permissive_pattern Check for regex and wildcard patterns that are overly permissive.
    http.host wildcard "*"
    http.request.uri.path matches "/.*"
  • regex_raw_strings Ensure regex matches use raw string literals (r"...") instead of normal quoted strings.
    http.host matches "example\.com"
  • replace_functions_limit regex_ and wildcard_replace functions are only allowed once and not nested.
    concat(regex_replace(http.host, r"www\.", ""), regex_replace(http.host, r"www\.", "")) eq "example.com"
    wildcard_replace(regex_replace(http.host, r"www\.", ""), "*.", "") eq "example.com"
  • reserved_ip_space Check for usage of reserved IP ranges that are unlikely to be useful in rules.
    ip.src eq 192.168.0.1
  • suspicious_regex Detect regexes that look like they should be wildcard matches or contain unescaped literal special characters.
    http.host matches "www.example.org"
    http.request.uri.path matches "/foo/bar/index.php"
    http.request.uri.path matches "/foo/bar/baz/*"
    http.request.uri matches "https://www.example.org/foo/index.html?query=args"
  • timestamp_comparisons Detect comparisons against http.request.timestamp.sec that use values outside of reasonable bounds.
    http.request.timestamp.sec gt 1104534000
    http.request.timestamp.sec lt 32503676400
  • unnecessary_patterns Detect regex and wildcard patterns that can be simplified to eq or contains expressions.
    http.host matches "example"
    http.host matches "^(ex|am|ple)$"
    http.host strict wildcard "example"
  • value_domain Check for values that are outside of the valid domain for certain fields, such as invalid HTTP methods or invalid continents.
    cf.edge.server_port eq 500000
    http.host eq "https://example.com"
    http.request.full_uri eq "www.example.com/foo/index.html"
    http.request.uri.path in {"/" "/foo" "index.html" "/bar"}
    ip.src.continent in {"NA" "AN" "FA" "EU"}