1. json

POST/PUT 请求,若使用 content-type application/json 则会被 naxsi 解析,payload被转换用于 whitelist / signatures writting 处理:

  • 所有目标为 BODY 的规则,会解析 json
  • 使用类似于 $BODY_VAR:xx 的 whitelists(or rules),会进行json解析

但是,对于json,naxsi最多处理10层。

有请求:

POST ...

{
"this" : { "will" : ["work", "does"],
"it" : "??" },
"tr<igger" : {"test_1234" : ["foobar", "will", "trigger", "it"]}
}


规则会匹配

MainRule "str:foobar" "msg:foobar test pattern" "mz:BODY" "s:$SQL:42" id:1999;


白名单

BasicRule wl:X "mz:$BODY_VAR:test_1234";


2. runtime modifiers

naxsi 提供了 一些 变量,用于控制 naxsi 行为。

  • naxsi_flag_learning : 如果存在,该变量会 重写 naxsi learning flag (0:disable lerning, 1 : enable)
  • naxsi_flag_post_action : 如果存在,并且设置为0,可以 disable post_action,在 learning mode
  • naxsi_flag_enable : 如果存在,变量会重写 SecRulesEnabled 执行(0:disable, 1 : enable)
  • naxsi_extensive_log : 如果存在,且设置为1,变量会强制 naxsi 记录 变量匹配规则 的内容
  • naxsi_flag_libinjection_sql : enable/disable libi_sql
  • naxsi_flag_libinjection_xss : enable/disable libi_xss
  • naxsi_json_log : 输出 json格式的 blocks/events

2.1 友情提示

有必要知道 naxsi 工作在 ngx的 rewrite 阶段。因此,直接在 loction 设置变量是无用的(因为naxsi在变量设置生效前被调用)

这是正确的

 set $naxsi_flag_enable 0;
location / {
...
}


这是错误的

 location / {
set $naxsi_flag_learning 1;
...
}


你能用 ngx,lua 改变 naxsi 的行为。

这些变量能 控制 learning mode ,naxsi,昂贵的日志 的 开关。所以,你能 动态决定naxsi行为,如

 # Disable naxsi if client ip is 127.0.0.1
if ($remote_addr = "127.0.0.1") {
set $naxsi_flag_enable 0;
}
 if ($remote_addr = "1.2.3.4") {
set $naxsi_flag_learning 1;
}
location / {
...
}

set $naxsi_flag_enable 0;
location / {
...
}


naxsi_extensive_log

如果被设置为1,会强制 记录 匹配变量的内容 到日志。默认记录到 error_log

 NAXSI_EXLOG: ip=%V&server=%V&uri=%V&id=%d&zone=%s&var_name=%V&content=%V


naxsi_flag_libinjection_sql

若设置为1,naxsi会传输 解析后的内容 给 libinjection,并查询 sql注入。如果匹配, 内部规则 libinjection_sql 触发

naxsi_flag_libinjection_xss

同上

naxsi_json_log

设置为1,强制naxsi 用json格式 记录 events/blocks。

json 输出 限制为 1948 字节,如果有更多数据,第二部分(多行日志)使用 空json,因为连接 大数据json 没有意义。

所以,如果 多行输出 发生,我会发送一个空json,你不需要连接json,这会很难进行json解析。

若多行输出,naxsi默认输出为:

2020/07/22 09:24:57 [error] 14714#0: *1 NAXSI_FMT: ip=127.0.0.1&server=localhost&uri=/&vers=0.56&total_processed=1&total_blocked=1&config=learning&cscore0=$SQL&score0=630&zone0=ARGS&id0=1998&var_name0=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1&zone1=ARGS&id1=1998&var_name1=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2&zone2=ARGS&id2=1998&var_name2=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3&zone3=ARGS&id3=1998&var_name3=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4&zone4=ARGS&id4=1998&var_name4=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5&zone5=ARGS&id5=1998&var_name5=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6&zone6=ARGS&id6=1998&var_name6=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa7&zone7=ARGS&id7=1998&var_name7=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8&zone8=ARGS&id8=1998&var_name8=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9&zone9=ARGS&id9=1998&var_name9=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10&zone10=ARGS&id10=1998&var_name10=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11&zone11=ARGS&id11=1998&var_name11=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12&zone12=ARGS&id12=1998&var_name12=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13&seed_start=185, client: 127.0.0.1, server: localhost, request: "GET /?AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
2020/07/22 09:24:57 [error] 14714#0: *1 NAXSI_FMT: seed_end=185&zone13=ARGS&id13=1998&var_name13=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14&zone14=ARGS&id14=1998&var_name14=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15, client: 127.0.0.1, server: localhost, request: "GET /?AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA10=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA11=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA12=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA13=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA14=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA15=1998 HTTP/1.1", host: "localhost"
As you can see they're connected by "seed_start" and "seed_end".


若开启json输出,json为空,而数据项以键值对形式 输出。

2020/07/22 09:24:57 [error] 14714#0: *1 { }, client: 127.0.0.1, server: localhost, request: "GET /?AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA10=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA11=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA12=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA13=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA14=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA15=1998 HTTP/1.1", host: "localhost"
2020/07/22 09:24:57 [error] 14714#0: *1 { }, client: 127.0.0.1, server: localhost, request: "GET /?AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA10=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA11=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA12=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA13=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA14=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA15=1998 HTTP/1.1", host: "localhost"


单行输出的json形式

2020/07/22 09:25:01 [error] 14714#0: *2 { "ip":"127.0.0.1","server":"localhost","uri":"/","vers":"0.56","total_processed":"2","total_blocked":"2","config":"learning","cscore0":"$XSS","score0":"16","zone0":"ARGS","id0":"1302","var_name0":"","zone1":"ARGS","id1":"1303","var_name1":"" }, client: 127.0.0.1, server: localhost, request: "GET /?<script> HTTP/1.1", host: "localhost"


3. libinjection

libinjection是第三方库,用于检测sqli xss。naxsi使用他的目的是:

  • 通用sqli/xss检查
  • 虚拟补丁

3.1 通用检测

libinjecttion 必须明确配置,才能启动。

通过 指令,LibInjectionXss LibInjectionSql 或 变量naxsi_flag_libinjection_xss and naxsi_flag_libinjection_sql 开启。

  • 通用 libinjection_xss 规则有内部规则 id 18,每次匹配 增加8分 $LIBINJECTION_XSS
  • 通用 libinjection_sql 规则有内部规则 id 17,每次匹配 增加17分 $LIBINJECTION_SQL

通用启动方法

location / {
SecRulesEnabled;
LibInjectionXss;
CheckRule "$LIBINJECTION_XSS >= 8" BLOCK;
...
}

location / {
SecRulesEnabled;
LibInjectionSql;
CheckRule "$LIBINJECTION_SQL >= 8" BLOCK;
...
}


当 通用检查开启,误杀白名单可以用 id17, id18 设置

动态开启

#/foobar as LOTS of sql injections
if ($request_uri ~ ^/foobar(.*)$ ) {
set $naxsi_flag_libinjection_sql 1;
}
...
location / {
...
CheckRule "$LIBINJECTION_SQL >= 8" DROP;
...
}


3.2 虚拟补丁

虽然 泛开启 libinjection 可能不能依赖域 应用上下文。

但是,libinjection 也可以被用作虚拟补丁

传输 GET变量内容为 'ruuu' 的请求给 libinjection,如果匹配就 drop

MainRule "d:libinj_xss" "s:DROP" "mz:$ARGS_VAR:ruuu" id:41231;


drop 任何 GET变量'ruuu' 触发 libinjection的请求

MainRule "d:libinj_sql" "s:DROP" "mz:$ARGS_VAR:ruuu" id:41231;