WAF规则操作符

WAF规则操作符是指被检查参数与对比值之间的对比方法。

规则操作符可以在添加规则和修改规则时在表单中选择。

数值大于

  • 名称:数值大于
  • 代号:gt
  • 描述:使用数值对比大于,对比值需要是一个数字

示例

比如我们需要判断一个URL某个参数值大于10:

  • 参数:单个URL参数值 - [arg]
  • 参数名:value
  • 操作符:数值大于
  • 对比值:10

那么:

https://example.com/?value=11  // 匹配
https://example.com/?value=10  // 不匹配
https://example.com/?value=9   // 不匹配

数值大于等于

  • 名称:数值大于等于
  • 代号:gte
  • 描述:使用数值对比大于等于,对比值需要是一个数字

示例

比如我们需要判断一个URL某个参数值大于等于10:

  • 参数:单个URL参数值 - [arg]
  • 参数名:value
  • 操作符:数值大于等于
  • 对比值:10

那么:

https://example.com/?value=11  // 匹配
https://example.com/?value=10  // 匹配
https://example.com/?value=9   // 不匹配

数值小于

  • 名称:数值小于
  • 代号:lt
  • 描述:使用数值对比小于,对比值需要是一个数字

示例

比如我们需要判断一个URL某个参数值小于10:

  • 参数:单个URL参数值 - [arg]
  • 参数名:value
  • 操作符:数值小于
  • 对比值:10

那么:

https://example.com/?value=11  // 不匹配
https://example.com/?value=10  // 不匹配
https://example.com/?value=9   // 匹配

数值小于等于

  • 名称:数值小于等于
  • 代号:lte
  • 描述:使用数值对比小于等于,对比值需要是一个数字

示例

比如我们需要判断一个URL某个参数值小于等于10:

  • 参数:单个URL参数值 - [arg]
  • 参数名:value
  • 操作符:数值小于等于
  • 对比值:10

那么:

https://example.com/?value=11  // 不匹配
https://example.com/?value=10  // 匹配
https://example.com/?value=9   // 匹配

数值等于

  • 名称:数值等于
  • 代号:eq
  • 描述:使用数值对比等于,对比值需要是一个数字

示例

比如我们需要判断一个URL某个参数值等于10:

  • 参数:单个URL参数值 - [arg]
  • 参数名:value
  • 操作符:数值等于
  • 对比值:10

那么:

https://example.com/?value=abc     // 不匹配
https://example.com/?value=10abc   // 不匹配
https://example.com/?value=11      // 不匹配
https://example.com/?value=10      // 匹配
https://example.com/?value=10.123  // 不匹配
https://example.com/?value=9       // 不匹配

数值不等于

  • 名称:数值不等于
  • 代号:neq
  • 描述:使用数值对比不等于,对比值需要是一个数字

示例

比如我们需要判断一个URL某个参数值不等于10:

  • 参数:单个URL参数值 - [arg]
  • 参数名:value
  • 操作符:数值不等于
  • 对比值:10

那么:

https://example.com/?value=11  // 匹配
https://example.com/?value=10  // 不匹配
https://example.com/?value=9   // 匹配

字符串等于

  • 名称:字符串等于
  • 代号:eq string
  • 描述:使用字符串对比等于

示例

比如我们需要判断一个URL路径中是否和 /js 字符串完全一样:

  • 参数:请求路径 - [requestPath](因为这里我们不需要判断域名,所以没有使用请求完整URL
  • 操作符:字符串等于
  • 对比值:/js

那么:

https://example.com/js         # 匹配
https://example.com/js1        # 不匹配  
https://example.com/JS         # 不匹配 
https://example.com/static/js  # 不匹配   

如果要允许 /JS/Js 也都能匹配,可以设置规则中的 不区分大小写

字符串不等于

  • 名称:字符串不等于
  • 代号:neq string
  • 描述:使用字符串对比不等于

示例

比如我们需要判断一个URL路径中是否和 /js 字符串不一样:

  • 参数:请求路径 - [requestPath](因为这里我们不需要判断域名,所以没有使用请求完整URL
  • 操作符:字符串等于
  • 对比值:/js

那么:

https://example.com/js         # 不匹配
https://example.com/js1        # 匹配  
https://example.com/JS         # 匹配 
https://example.com/static/js  # 匹配   

如果要允许 /JS/Js 也都不匹配,可以设置规则中的 不区分大小写

正则匹配

  • 名称:正则匹配
  • 代号:match
  • 描述:使用正则表达式匹配,在头部使用(?i)表示不区分大小写,正则表达式语法

示例1

比如我们需要判断一个URL路径中是否包含 /scriptjs

  • 参数:请求路径 - [requestPath](因为这里我们不需要判断域名,所以没有使用请求完整URL
  • 操作符:正则匹配
  • 对比值:/script|/js (用|符号表示的关系)

那么:

https://example.com/js                    # 匹配
https://example.com/script                # 匹配
https://example.com/static/script/search  # 匹配
https://example.com/static/javascript     # 匹配,包含了 script
https://example.com/static/scriptfiles    # 匹配,包含了 script
https://example.com/static/scr            # 不匹配
https://example.com/static/SCRIPT         # 不匹配

如果要允许 /SCRIPT/JS 也都匹配,可以设置规则中的 不区分大小写

示例2

比如我们需要判断用户的User-Agent中是否包含一些常用的手机浏览器标识:

  • 参数:客户端信息 - [userAgent]
  • 操作符:正则匹配
  • 对比值:iPhone|iPad|Android (用|符号表示的关系)

那么:

Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15            # 匹配
Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15   # 匹配
Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36                            # 匹配
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/605.1.15          # 不匹配

如果要允许 iphoneandroid 也都匹配,可以设置规则中的 不区分大小写

正则不匹配

  • 名称:正则不匹配
  • 代号:not match
  • 描述:使用正则表达式不匹配,在头部使用(?i)表示不区分大小写,正则表达式语法

示例

比如我们需要判断一个URL路径中是否不包含 /scriptjs

  • 参数:请求路径 - [requestPath](因为这里我们不需要判断域名,所以没有使用请求完整URL
  • 操作符:正则不匹配
  • 对比值:/script|/js (用|符号表示的关系)

那么:

https://example.com/js                    # 不匹配
https://example.com/script                # 不匹配
https://example.com/static/script/search  # 不匹配
https://example.com/static/javascript     # 不匹配,包含了 script
https://example.com/static/scriptfiles    # 不匹配,包含了 script
https://example.com/static/scr            # 匹配
https://example.com/static/SCRIPT         # 匹配

如果要允许 /SCRIPT/JS 也都不匹配,可以设置规则中的 不区分大小写

包含字符串

  • 名称:包含字符串
  • 代号:contains
  • 描述:包含某个字符串,比如Hello World包含了World;每个规则只能填入一个被包含字符串;不能使用正则表达式

示例

比如我们需要判断一个URL路径中是否包含 /js

  • 参数:请求路径 - [requestPath](因为这里我们不需要判断域名,所以没有使用请求完整URL
  • 操作符:包含字符串
  • 对比值:/js

那么:

https://example.com/js                   # 匹配
https://example.com/static/js/search     # 匹配
https://example.com/static/jscripts      # 匹配,包含了 js
https://example.com/static/JS            # 不匹配
https://example.com/static/sj            # 不匹配

如果要允许 /JS/Js 也都匹配,可以设置规则中的 不区分大小写

不包含字符串

  • 名称:不包含字符串
  • 代号:not contains
  • 描述:不包含某个字符串,比如Hello字符串中不包含Hi;每个规则只能填入一个被检查字符串;不能使用正则表达式

示例

比如我们需要判断一个URL路径中是否不包含 /js

  • 参数:请求路径 - [requestPath](因为这里我们不需要判断域名,所以没有使用请求完整URL
  • 操作符:不包含字符串
  • 对比值:/js

那么:

https://example.com/js                   # 不匹配
https://example.com/static/js/search     # 不匹配
https://example.com/static/jscripts      # 不匹配,包含了 js
https://example.com/static/JS            # 匹配
https://example.com/static/sj            # 匹配

如果要允许 /JS/Js 也都不匹配,可以设置规则中的 不区分大小写

包含任一字符串

  • 名称:包含任一字符串
  • 代号:contains any
  • 描述:包含字符串列表中的任意一个,比如/hello/world包含/hello和/hi中的/hello,每行一个字符串

示例

比如我们需要判断一个URL路径中是否包含 /js/script

  • 参数:请求路径 - [requestPath](因为这里我们不需要判断域名,所以没有使用请求完整URL
  • 操作符:包含任一字符串
  • 对比值:使用换行隔开多个值:
    /js
    /script

那么:

https://example.com/js                   # 匹配
https://example.com/static/js/search     # 匹配
https://example.com/static/jscripts      # 匹配,包含了 js和script
https://example.com/static/script        # 匹配,包含了 script
https://example.com/static/JS            # 不匹配
https://example.com/static/sj            # 不匹配

如果要允许 /SCRIPT/Js 也都匹配,可以设置规则中的 不区分大小写

包含所有字符串

  • 名称:包含所有字符串
  • 代号:contains all
  • 描述:包含字符串列表中的所有字符串,比如/hello/world必须包含/hello和/world,每行一个字符串

示例

比如我们需要判断一个URL路径中是否同时包含 /js/script

  • 参数:请求路径 - [requestPath](因为这里我们不需要判断域名,所以没有使用请求完整URL
  • 操作符:包含所有字符串
  • 对比值:使用换行隔开多个值:
    /js
    /script

那么:

https://example.com/js                   # 不匹配
https://example.com/static/js/search     # 不匹配
https://example.com/js/script            # 匹配,同时包含了 js和script
https://example.com/static/jscripts      # 匹配,同时包含了 js和script
https://example.com/static/script        # 不匹配
https://example.com/static/JS            # 不匹配
https://example.com/static/sj            # 不匹配

如果要允许 /JS/SCRIPT 也都匹配,可以设置规则中的 不区分大小写

包含前缀

  • 名称:包含前缀
  • 代号:prefix
  • 描述:包含字符串前缀部分,比如/hello前缀会匹配/hello, /hello/world等;每个规则只能填入一个前缀;不能使用正则表达式

示例

比如我们需要判断一个URL路径中是否以 /js 开头:

  • 参数:请求路径 - [requestPath](因为这里我们不需要判断域名,所以没有使用请求完整URL
  • 操作符:包含前缀
  • 对比值:/js

那么:

https://example.com/js                   # 匹配
https://example.com/static/js/search     # 不匹配
https://example.com/static/JS            # 不匹配
https://example.com/static/sj            # 不匹配

如果要允许 /JS/Js 也都匹配,可以设置规则中的 不区分大小写

包含后缀

  • 名称:包含后缀
  • 代号:suffix
  • 描述:包含字符串后缀部分,比如/hello后缀会匹配/hello, /hi/hello等;每个规则只能填入一个前缀;不能使用正则表达式

示例

比如我们需要判断一个URL路径中是否以 /js 结尾:

  • 参数:请求路径 - [requestPath](因为这里我们不需要判断域名,所以没有使用请求完整URL
  • 操作符:包含后缀
  • 对比值:/js

那么:

https://example.com/js                   # 匹配
https://example.com/static/js            # 匹配
https://example.com/js/search            # 不匹配
https://example.com/static/JS            # 不匹配
https://example.com/static/sj            # 不匹配

如果要允许 /JS/Js 也都匹配,可以设置规则中的 不区分大小写

包含任一单词

  • 名称:包含任一单词
  • 代号:contains any word
  • 描述:包含某个独立单词,对比值中每行一个单词,比如mozilla firefox里包含了mozilla和firefox两个单词,但是不包含fire和fox这两个单词

示例

比如我们需要判断一个User-Agent是否包含ChromeFirefox两个单词中的一个:

  • 参数:客户端信息 - [userAgent]
  • 操作符:包含任一单词
  • 对比值:使用换行隔开多个值:
    Chrome
    Firefox

那么:

Mozilla/5.0 Chrome/119.0.0.0 Safari/537.36      # 匹配
Mozilla/5.0 Firefox/120.0                       # 匹配
Mozilla/5.0 Safari/605.1.15                     # 不匹配
Mozilla/5.0 FakeFirefox/120.0                   # 不匹配(因为不是单独的Firefox)
Mozilla/5.0 firefox/120.0                       # 不匹配(因为firefox首字母大小写不相同,除非设置了不区分大小写)

包含所有单词

  • 名称:包含所有单词
  • 代号:contains all words
  • 描述:包含所有的独立单词,对比值中每行一个单词,比如mozilla firefox里包含了mozilla和firefox两个单词,但是不包含fire和fox这两个单词

示例

比如我们需要判断一个User-Agent是否同时包含ChromeSafari两个单词:

  • 参数:客户端信息 - [userAgent]
  • 操作符:包含所有单词
  • 对比值:使用换行隔开多个值:
    Chrome
    Safari

那么:

Mozilla/5.0 Chrome/119.0.0.0 Safari/537.36      # 匹配(同时包含Chrome和Safari)
Mozilla/5.0 Firefox/120.0                       # 不匹配
Mozilla/5.0 Safari/605.1.15                     # 不匹配(只匹配到一个)
Mozilla/5.0 Chrome/119.0.0.0 FakeSafari/537.36  # 不匹配(因为不是单独的Safari)
Mozilla/5.0 Chrome/119.0.0.0 safari/537.36      # 不匹配(因为safari首字母大小写不相同,除非设置了不区分大小写)

不包含任一单词

  • 名称:不包含任一单词
  • 代号:contains any word
  • 描述:不包含某个独立单词,对比值中每行一个单词,比如mozilla firefox里包含了mozilla和firefox两个单词,但是不包含fire和fox这两个单词

示例

比如我们需要判断一个User-Agent是否包含ChromeFirefox两个单词中的一个:

  • 参数:客户端信息 - [userAgent]
  • 操作符:不包含任一单词
  • 对比值:使用换行隔开多个值:
    Chrome
    Firefox

那么:

Mozilla/5.0 Chrome/119.0.0.0 Safari/537.36      # 不匹配
Mozilla/5.0 Firefox/120.0                       # 不匹配
Mozilla/5.0 Safari/605.1.15                     # 匹配
Mozilla/5.0 FakeFirefox/120.0                   # 匹配(因为不是单独的Firefox)
Mozilla/5.0 firefox/120.0                       # 匹配(因为firefox首字母大小写不相同,除非设置了不区分大小写)

包含SQL注入

  • 名称:包含SQL注入
  • 代号:contains sql injection
  • 描述:检测字符串内容是否包含SQL注入

示例

比如我们要检测用户的访问URL中是否包含SQL注入,可以添加以下规则:

  • 参数:请求URI - [requestURI]
  • 操作符:包含SQL注入
  • 对比值:不需要填写

那么:

/index?id=123 or 1=1        # 匹配
/index?id=123%20or%201=1    # 匹配(会自动对URL中参数进行解码)
/index?id=123 union select  # 匹配
/index?id=123               # 不匹配(正常参数)

包含SQL注入-严格模式

  • 名称:包含SQL注入
  • 代号:contains sql injection strictly
  • 描述:更加严格地检测字符串内容是否包含SQL注入,相对于非严格模式,有一定的误报几率

包含XSS注入

  • 名称:包含XSS注入
  • 代号:contains xss
  • 描述:检测字符串内容是否包含XSS注入

示例

比如我们要检测用户的访问URL中是否包含XSS注入,可以添加以下规则:

  • 参数:请求URI - [requestURI]
  • 操作符:包含XSS注入
  • 对比值:不需要填写

那么:

/index?id=123%20<script                  # 匹配(包含<script)
/index?<html><body><link></body></html>  # 匹配(包含<link>)
/index?<html><body></body></html>        # 不匹配(没有外链标签)
/index?id=123                            # 不匹配(正常参数)

包含XSS注入-严格模式

  • 名称:包含XSS注入
  • 代号:contains xss strictly
  • 描述:更加严格地检测字符串内容是否包含XSS注入,相对于非严格模式,此时xml、audio、video等标签也会被匹配

示例

比如我们要检测用户的访问URL中是否包含XSS注入,可以添加以下规则:

  • 参数:请求URI - [requestURI]
  • 操作符:包含XSS注入-严格模式
  • 对比值:不需要填写

那么:

/index?id=123%20<script                  # 匹配(包含<script)
/index?<html><body><link></body></html>  # 匹配(包含<link>)
/index?<html><body></body></html>        # 不匹配(没有外链标签)
/index?id=123                            # 不匹配(正常参数)
/index?id=<xml>123</xml>                 # 匹配(严格模式下对XML、AUDIO等标签也会匹配)

包含二进制数据

  • 名称:包含二进制数据
  • 代号:contains binary
  • 描述:包含一组二进制数据

不包含二进制数据

  • 名称:不包含二进制数据
  • 代号:not contains binary
  • 描述:不包含一组二进制数据

包含索引

  • 名称:包含索引
  • 代号:has key
  • 描述:对于一组数据拥有某个键值或者索引

版本号大于

  • 名称:版本号大于
  • 代号:version gt
  • 描述:对比版本号大于

版本号小于

  • 名称:版本号小于
  • 代号:version lt
  • 描述:对比版本号小于

版本号范围

  • 名称:版本号范围
  • 代号:version range
  • 描述:判断版本号在某个范围内,格式为version1,version2

IP等于

  • 名称:IP等于
  • 代号:eq ip
  • 描述:将参数转换为IP进行对比,只能对比单个IP

在一组IP中

  • 名称:在一组IP中
  • 代号:in ip list
  • 描述:判断参数IP在一组IP内,每行一个IP

示例

比如我们需要判断客户端地址是否在一组IP内:

  • 参数:客户端地址(IP)- [remoteAddr]
  • 操作符:在一组IP中
  • 对比值:填入多行,每行一个IP:
    192.168.2.40
    192.168.3.50
    192.168.4.100

那么:

192.168.2.40     #  匹配
192.168.3.50     #  匹配
192.168.4.100    #  匹配
192.168.2.101    # 不匹配
192.168.1.100    # 不匹配

IP大于

  • 名称:IP大于
  • 代号:gt ip
  • 描述:将参数转换为IP进行对比

IP大于等于

  • 名称:IP大于等于
  • 代号:gte ip
  • 描述:将参数转换为IP进行对比

IP小于

  • 名称:IP小于
  • 代号:lt ip
  • 描述:将参数转换为IP进行对比

IP小于等于

  • 名称:IP小于等于
  • 代号:lte ip
  • 描述:将参数转换为IP进行对比

IP范围

  • 名称:IP范围
  • 代号:ip range
  • 描述:IP在某个范围之内,范围格式可以是英文逗号分隔的开始IP,结束IP,比如192.168.1.100,192.168.2.200;或者CIDR格式的ip/bits,比如192.168.2.1/24;或者单个IP。可以填写多行,每行一个IP范围。

示例1 - CIDR

比如我们需要判断客户端地址是否在一个范围内:

  • 参数:客户端地址(IP)- [remoteAddr]
  • 操作符:IP范围
  • 对比值:192.168.2.1/24

那么:

192.168.2.40   # 匹配
192.168.1.100  # 不匹配

示例2 - IP段

比如我们需要判断客户端地址是否在一个范围内:

  • 参数:客户端地址(IP)- [remoteAddr]
  • 操作符:IP范围
  • 对比值:192.168.2.1,192.168.2.100 (表示从192.168.2.1192.168.2.100

那么:

192.168.2.40    #  匹配
192.168.2.101   # 不匹配
192.168.1.100   # 不匹配

对比值也可以用中划线分隔,类似于192.168.2.1-192.168.2.100

示例3 - 多个IP

比如我们需要判断客户端地址是否在一组范围内:

  • 参数:客户端地址(IP)- [remoteAddr]
  • 操作符:IP范围
  • 对比值:填入多行,既可以是CIDR格式,也可以是IP段,还可以是单个IP:
    192.168.2.40
    192.168.3.1/24
    192.168.4.100-192.168.4.200

那么:

192.168.2.40     #  匹配
192.168.3.50     #  匹配
192.168.4.100    #  匹配
192.168.2.101    # 不匹配
192.168.1.100    # 不匹配

不在IP范围

  • 名称:不在IP范围
  • 代号:not ip range
  • 描述:IP不在某个范围之内,范围格式可以是英文逗号分隔的开始IP,结束IP,比如192.168.1.100,192.168.2.200;或者CIDR格式的ip/bits,比如192.168.2.1/24;或者单个IP。可以填写多行,每行一个IP范围。

具体示例请参考本文的 IP范围

IP取模10

  • 名称:IP取模10
  • 代号:ip mod 10
  • 描述:对IP参数值取模,除数为10,对比值为余数

IP取模100

  • 名称:IP取模100
  • 代号:ip mod 100
  • 描述:对IP参数值取模,除数为100,对比值为余数

IP取模

  • 名称:IP取模
  • 代号:ip mod
  • 描述:对IP参数值取模,对比值格式为:除数,余数,比如10,1