Space .htaccess 中的正则表达式不匹配字符

Space character not being matched by regex in .htaccess

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

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

除包含 space 字符的请求外,其他都有效,例如

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

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

我需要更改什么?

(是的,错误的用户输入在我的 PHP 中处理,因此是否通过并不重要)

也许这对你有用:

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 等也将包含在其中。

@Andreykul spaces are encoded for requests from regular browsers yes, but these are requests probing for vulnerabilities.

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

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

"problem" 这是一个 invalid/malformed 请求。要使其有效,它 必须 被 URL 编码。 (文字)space 是请求第一行中的特殊字符,用作 "Method"、"Request-URI" 和 "HTTP-Version" header.

的部分

由于请求 无效 ,因此可以合理地预期它已在服务器级别被 400 Bad Request.

阻止

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

对于这样的请求,如果您检查 QUERY_STRING 服务器变量,您会发现它不包含 space 或第二个 5。该值在 文字 space 之前被截断 ,它仅包含 ID=5。 (因此,这也是 PHP 看到的。)因此,您的正则表达式 (CondPattern) 永远不会匹配。

但是,完整的请求 URI 出现在请求的第一行(如您在上面发布的那样)- 这在 THE_REQUEST Apache 服务器变量中可用。最好简单地阻止任何包含文字 spaces 的请求(无论如何 无效 ),而不是专门搜索包含 ID 参数的请求.例如:

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

这会检查外部 space 分隔符之间是否包含任何白色 space。

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