我想阻止任何包含使用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中处理的,所以如果通过它并不重要)
答案 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]
这将检查外层空格分隔符之间包含的任何空格。