空格字符与.htaccess中的正则表达式不匹配

时间:2017-06-13 19:16:47

标签: regex .htaccess mod-rewrite pcre

我想阻止任何包含使用mod_rewite或空ID的包含任何非数字字符的ID的请求。我在.htaccess文件中有以下规则:

RewriteCond %{QUERY_STRING} ID=(\d*[^\d&]+\d*)*(&|$)
RewriteRule .* - [F]

除了包含空格字符的请求之外,其他工作正常工作,例如。

GET /page.php?ID=5 5 HTTP/1.1

当我使用各种测试套件(例如https://regex101.com/)时,两个5s之间的空格字符与[^\d&]+成功匹配,但此类请求仍在通过。

我需要改变什么?

(是的,不正确的用户输入是在我的PHP中处理的,所以如果通过它并不重要)

2 个答案:

答案 0 :(得分:3)

也许这对你有用:

RewriteCond %{QUERY_STRING} !(?:^|&)ID=\d+(?:&|$)
RewriteRule ^ - [F]

如果您只希望它影响查询字符串中具有ID参数的请求(因此允许不带ID的请求):

RewriteCond %{QUERY_STRING} (?:^|&)(?:\%(?:20|09))*ID(?:\%(?:20|09))*= [NC]
RewriteCond %{QUERY_STRING} !(?:^|&)ID=\d+(?:&|$)
RewriteRule ^ - [F]

我还添加了[NC](不区分大小写),以便iD等也包括在内。

答案 1 :(得分:2)

  

@Andreykul空间是针对来自常规浏览器的请求编码的,但这些是探测漏洞的请求。

网络服务器本身可能存在漏洞,而不是您的网络应用程序......(?)

GET /page.php?ID=5 5 HTTP/1.1

这个问题是它是一个无效/格式错误的请求。为使其有效,必须进行URL编码。 (literal) space 是请求第一行中的特殊字符,用作标题的“Method”,“Request-URI”和“HTTP-Version”部分之间的分隔符。

由于请求无效,因此可以合理地预期它已在服务器级别使用400 Bad Request进行阻止。

如果服务器没有阻止请求,那么您可能会遇到意外行为。这可能就是你在这里看到的......

对于此类请求,如果检查QUERY_STRING服务器变量,您将看到它不包含空格或第二个5。该值在文字空间之前被截断,它只包含ID=5。 (因此,这也是PHP看到的。)因此,你的正则表达式( CondPattern )从不匹配。

但是,完整的请求URI存在于请求的第一行(如上所述) - 这在THE_REQUEST Apache服务器变量中可用。最好只是阻止任何包含文字空格的请求(无论如何都无效),而不是专门搜索包含ID参数的请求。例如:

RewriteCond %{THE_REQUEST} \s.*\s.*\s
RewriteRule ^ - [R=400]

这将检查外层空格分隔符之间包含的任何空格。

参考:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html