{{i18nTranslate('_layout.t11')}} {{i18nGetLang()==='zh' ? 'EN' : '中文'}}

# 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路径中是否包含 `/script` 或 `js`：

- 参数：`请求路径 - [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          # 不匹配

如果要允许 `iphone` 和 `android` 也都匹配，可以设置规则中的 `不区分大小写`。

## 正则不匹配

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

### 示例

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

- 参数：`请求路径 - [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这两个单词
- 版本：GoEdge v1.3.2

### 示例

比如我们需要判断一个User-Agent是否包含`Chrome`和`Firefox`两个单词中的一个：

- 参数：`客户端信息 - [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这两个单词
- 版本：GoEdge v1.3.2

### 示例

比如我们需要判断一个User-Agent是否同时包含`Chrome`和`Safari`两个单词：

- 参数：`客户端信息 - [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这两个单词
- 版本：GoEdge v1.3.2

### 示例

比如我们需要判断一个User-Agent是否不包含`Chrome`和`Firefox`两个单词中的一个：

- 参数：`客户端信息 - [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注入
- 版本：GoEdge v1.3.2

### 示例

比如我们要检测用户的访问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注入，相对于非严格模式，有一定的误报几率
- 版本：GoEdge v1.3.3

## 包含XSS注入

- 名称：包含XSS注入
- 代号：`contains xss`
- 描述：检测字符串内容是否包含XSS注入
- 版本：GoEdge v1.3.2

### 示例

比如我们要检测用户的访问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等标签也会被匹配
- 版本：GoEdge v1.3.3

### 示例

比如我们要检测用户的访问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范围

> 注意：在GoEdge v0.6.0以前，”IP范围”操作符对比值中只能填写单个IP范围；在v0.6.0以后可以填写多个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.1`到`192.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范围

> 注意：在GoEdge v0.6.0以前，”不在IP范围”操作符对比值中只能填写单个IP范围；在v0.6.0以后可以填写多个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

{{i18nTranslate('_layout.t27')}}
{{i18nTranslate('_layout.t12')}}