如何跳过 ModSecurity 路径中参数的某些规则?

How do I skip certains rules for parameter in a path in ModSecurity?

我做了很多研究,发现了很多东西,但一直无法确定可以完成我需要它做的事情的东西。首先,我在 CentOS 7 服务器上 运行ning ModSecurity 2.7.3.

目标

我希望能够通过已设置的所有标准核心规则扫描除某些参数之外的所有参数并运行它们。例如,如果我有一个文件 path/to/myfile.php,它有 2 个参数发送给它 param1param2。当用户点击 myfile.php 时,我希望它 运行 它可以针对 param1param2 进行所有可爱的检查,除了 param2 我不需要它检查 WEB_ATTACK/XSS 因为它应该为该字段(或其他)期待一些 HTML。

警告

我认为我不能通过 ID 删除规则(除非我的理解有问题)。我们目前正在临时服务器上进行设置,然后我们将安装 ModSecurity 和我们在临时服务器上设置的排除项,并将它们复制到实时服务器。我不认为规则 ID 会与登台日志匹配(再次除非我误解了什么)并且不会 "fun" 将 ModSecurity 扔到我们的实时服务器上并等待规则开始跳闸.

到目前为止我得到了什么

这是我试过的...

<LocationMatch /path/to/myfile.php>
 <IfModule mod_security2.c>
    SecRuleEngine Off # This is super bad I know
 </IfModule>
</LocationMatch>

这是个坏主意,所以我可以这样做...

<LocationMatch /path/to/myfile.php>
 <IfModule mod_security2.c>
    SecRuleRemoveByTag "WEB_ATTACK/XSS" # better but.....still not close enough
 </IfModule>
</LocationMatch>

所以我尝试了以下内容但没有成功:

SecRule ARGS|!ARGS:param2 "@detectXSS" # only 2.8.0 and above :(
# or
SecRule ARGS|!ARGS:param2 "ctl:ruleRemoveByTag=WEB_ATTACK/XSS"
# or
SecRule REQUEST_FILENAME "@streq /path/to/myfile.php" "pass,ctl:ruleRemoveByTag=WEB_ATTACK/XSS;ARGS:param2"

ModSecurity 的文档......很好,但我需要更深入的理解,尤其是 ctl stuff. I also looked at some other questions here and here and seen some posts around the web that helped steer me in the right direction here (very nice write up), here, here, and here

奖励积分

如果我需要执行 param2 和 param3,我是否必须编写 2 条规则或者它们可以以某种方式组合 (ARGS:param2,param3)?

您对 ID 的理解 存在缺陷。规则 id 应该 在登台和实时上相同 - 除非你对它们有 运行 不同的规则(如果不是真的,这会破坏登台服务器的意义活像)。大多数人下载、购买或编写规则集,其中 OWASP 核心规则集是一个流行的(免费的!)规则集。

在您链接到但 ID 为

ctl documentation 中,有一个与您想要执行的操作几乎相同的示例
# white-list the user parameter for rule #981260 when the REQUEST_URI is /index.php
 SecRule REQUEST_URI "@beginsWith /index.php" "phase:1,t:none,pass, \
  nolog,ctl:ruleRemoveTargetById=981260;ARGS:user

所以对你来说这将变成:

SecRule REQUEST_URI "@beginsWith /path/to/myfile.php" "id:1234,phase:2,t:none,pass, \
  nolog,ctl:ruleRemoveTargetById=973336;ARGS:param2

请注意 OWASP CRS(不确定您是否正在使用它?)XSS 检查是第 2 阶段检查,因此我更改了它并且 ID 现在从 2.7 开始是强制性的。您可以扩展它以包括很多规则 ID 或不同的参数:

SecRule REQUEST_URI "@beginsWith /path/to/myfile.php" "phase:2,t:none,pass, \
  nolog,ctl:ruleRemoveTargetById=973336;ARGS:param2,\
  ctl:ruleRemoveTargetById=973337;ARGS:param2,\
  ctl:ruleRemoveTargetById=973338;ARGS:param2,\
  ctl:ruleRemoveTargetById=973336;ARGS:param3

但是,设置所有 ID 有点乏味,因此,如果您想通过标签来完成,您可以尝试以下方法,虽然未经测试,但应该可以工作:

SecRule REQUEST_URI "@beginsWith /path/to/myfile.php" "id:1234,phase:2,t:none,pass, \
  nolog,ctl:ruleRemoveTargetById="OWASP_CRS/WEB_ATTACK/XSS";ARGS:param2

请注意,OWASP CRS 标签实际上是 "OWASP_CRS/WEB_ATTACK/XSS" 而不仅仅是 "WEB_ATTACK/XSS" 并且不确定它是否会匹配部分位所以将全文放入,假设这是规则集你正在使用

同样,如果您确实想以类似方式将 param3 列入白名单,则可以在此行中执行多个 ctl 操作。

如果 none 有效,您可以使用链式规则代替 ctl 操作:

SecRule REQUEST_URI "@beginsWith /path/to/myfile.php" "id:1234,phase:2,t:none,pass,chain \
     SecRuleUpdateTargetByTag "OWASP_CRS:WEB_ATTACK/XSS" !ARGS:param2

这允许检查多个项目,如果没有等效的 ctl 命令(尽管 ctl 似乎可以处理大多数事情),您还可以访问所有 ModSecurity 规则命令。尽管每个参数都需要一个链式规则。

重要说明: 顺序很重要且令人困惑。 SecRuleUpdateTargetByTag 应指定 AFTER 他们正在更改的规则,但需要指定 ctl amends BEFORE 他们正在修改的规则。

还应注意,Location 和 LocationMatch 不适用于第 1 阶段规则(因为这些是在 Apache 运行 Location 和 LocationMatch 逻辑之前处理的)因此,出于这个原因,我更喜欢使用 ModSecurity REQUEST_URI。即使对于第 2 阶段及以上规则,为了保持一致性,它们也应该在 Location 和 LocationMatch 部分中工作。

最后,您可以(并且应该!)将 ModSecurity 最初以 DetectionOnly 模式放在您的实时服务器上,这样它会记录所有违规行为但不会阻止它们:

SecRuleEngine DetectionOnly

然后,当您微调规则时,您会发现误报率有所下降,直到您可以完全打开它为止。

顺便说一句,我强烈推荐 the ModSecurity handbook written by the original author of ModSecurity before he moved on. Hasn't been updated since ModSecurity 2.6 but, other than id becoming mandatory, everything it covers is still relevant and will give you a good grounding in ModSecurity and then you can check out the ModSecurity release notes (either in your install or here) 看看有什么变化。还建议您升级到最新版本 (2.9.1),因为自 2.7.3 以来修复了很多错误。