ModSecurity:按值列出的白名单参数

时间:2016-08-03 03:46:04

标签: apache mod-security

我尝试为名称未知但与值匹配的参数设置ModSecurity白名单。例如,我想将任何时间戳参数列入白名单(例如timestamp=2016-01-01 00:00:00)。目前,这会触发规则981173 (Restricted SQL Character Anomaly Detection Alert - Total # of special characters exceeded)

以下方法可行,但如果至少有一个匹配,则会跳过对所有参数的检查,因此它不会捕获badvalue中的https://www.example.com/?timestamp=2016-01-01+00:00:00&badvalue=2016-01-01+00:00:00:00参数。

SecRule ARGS "@rx ^2[0-9]{3}-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]$" \
    "id:'99001', phase:1, nolog, pass, t:none, \
    ctl:ruleRemoveTargetByTag=OWASP_CRS/WEB_ATTACK/SQL_INJECTION;ARGS"

如果我对参数名称进行硬编码,则以下情况有效。

SecRule ARGS:timestamp "@rx ^2[0-9]{3}-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]$" \
    "id:'99001', phase:1, nolog, pass, t:none, \
    ctl:ruleRemoveTargetByTag=OWASP_CRS/WEB_ATTACK/SQL_INJECTION;ARGS:timestamp"

我已尝试过以下方法,但他们还没有工作。

SecRule ARGS "@rx ^2[0-9]{3}-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]$" \
    "id:'99001', phase:1, nolog, pass, t:none, \
    ctl:ruleRemoveTargetByTag=OWASP_CRS/WEB_ATTACK/SQL_INJECTION;/%{MATCHED_VAR_NAME}/"

SecRule ARGS "@rx ^2[0-9]{3}-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]$" \
    "id:'99001', phase:1, nolog, pass, t:none, \
    ctl:ruleRemoveTargetByTag=OWASP_CRS/WEB_ATTACK/SQL_INJECTION;MATCHED_VAR_NAME"

ModSecurity可以实现吗?有没有办法在这个用例中使用MATCHED_VAR_NAME?我宁愿不必为每个可能包含时间戳的参数名称添加规则。

1 个答案:

答案 0 :(得分:0)

不幸的是,目前无法在ctl action参数中使用Macro Expansion。

作为证据,请考虑以下示例:

SecRule ARGS "@contains bob" "id:1,t:none,pass,ctl:ruleRemoveTargetById=2;ARGS:x"
SecRule ARGS "@contains hello" "id:2,deny,status:403"

提供以下请求时:'http://localhost/?x=bobhello'我们会在评估第二条规则时在调试日志中看到以下内容

  

[04 / Aug / 2016:00:44:07 - 0400] [localhost / sid#55e47aa583e0] [摆脱#55e47ad7cb10] [/] [4]食谱:调用规则55e47ab14638; [file“/etc/httpd/modsecurity.d/includeOWASP.conf”] [line“12”] [id“2”]。   [04 / Aug / 2016:00:44:07 - 0400] [localhost / sid#55e47aa583e0] [摆脱#55e47ad7cb10] [/] [5]规则55e47ab14638:SecRule“ARGS”“@contains hello”“阶段:2 ,日志,审计日志,ID:2,拒绝,状态:403"   [04 / Aug / 2016:00:44:07 - 0400] [localhost / sid#55e47aa583e0] [rid#55e47ad7cb10] [/] [4]转换在0 usec中完成。   [04 / Aug / 2016:00:44:07 - 0400] [localhost / sid#55e47aa583e0] [摆脱#55e47ad7cb10] [/] [9] fetch_target_exception:找到异常目标列表[ARGS:x] for rule id 2   [04 / Aug / 2016:00:44:07 - 0400] [localhost / sid#55e47aa583e0] [摆脱#55e47ad7cb10] [/] [9] fetch_target_exception:目标ARGS:不会处理x。   [04 / Aug / 2016:00:44:07 - 0400] [localhost / sid#55e47aa583e0] [rid#55e47ad7cb10] [/] [4]执行操作符“contains”,使用参数“hello”对抗ARGS:x跳过。   [04 / Aug / 2016:00:44:07 - 0400] [localhost / sid#55e47aa583e0] [摆脱#55e47ad7cb10] [/] [4]规则返回0。

但是,当我们提供相同的请求('http://localhost/?x=bobhello')时,我们的ctl操作中有宏扩展(如下所示):

SecRule ARGS "@contains bob" "id:1,t:none,pass,ctl:ruleRemoveTargetById=2;%{MATCHED_VAR_NAME}"
SecRule ARGS "@contains hello" "id:2,deny,status:403"

我们的调试日志将如下所示:

  

[04 / Aug / 2016:00:44:41 - 0400] [localhost / sid#559f82a0b3e0] [rid#559f82d2fb50] [/] [5]规则559f82ac76e8:SecRule“ARGS”“@contains hello”“阶段:2,日志,审计日志,ID:2,拒绝,状态:403"   [04 / Aug / 2016:00:44:41 - 0400] [localhost / sid#559f82a0b3e0] [rid#559f82d2fb50] [/] [4]转换在0 usec中完成。   [04 / Aug / 2016:00:44:41 - 0400] [localhost / sid#559f82a0b3e0] [摆脱#559f82d2fb50] [/] [9] fetch_target_exception:找到异常目标列表[%{MATCHED_VAR_NAME}] < / strong>用于规则ID 2   [04 / Aug / 2016:00:44:41 - 0400] [localhost / sid#559f82a0b3e0] [rid#559f82d2fb50] [/] [4]对ARGS执行操作符“contains”和param“hello”:x。   [04 / Aug / 2016:00:44:41 - 0400] [localhost / sid#559f82a0b3e0] [摆脱#559f82d2fb50] [/] [9]目标值:“bobhello”   [04 / Aug / 2016:00:44:41 - 0400] [localhost / sid#559f82a0b3e0] [rid#559f82d2fb50] [/] [4]运算符在2 usec中完成。   [04 / Aug / 2016:00:44:41 - 0400] [localhost / sid#559f82a0b3e0] [摆脱#559f82d2fb50] [/] [4]规则返回1.

我无法想到一种在没有过多开销的情况下实现这一目标的方法。此时,最佳解决方案可能是手动将每个有争议的参数列入白名单。