【问题标题】:Mod rewrite query parameter validation and blocking also request url blockingMod重写查询参数验证和阻塞也请求url阻塞
【发布时间】:2019-09-25 04:06:36
【问题描述】:

在我的网站上,只允许少数查询参数,但是,一些扫描程序或黑客试图使用我的 php 应用程序不支持的唯一参数访问 url,我可以通过验证 $_GET 在 php 应用程序级别阻止它们参数,但我的服务器正在加载,所以如果参数无效,我想显示 403

查询参数可以是任意顺序

目前我尝试的如下

# IF there is query string
RewriteCond %{QUERY_STRING} ^.+$

# Then parameters can be only query|debug|lang
# block any extra parameter
RewriteCond %{QUERY_STRING} !(^|$)(query|debug|lang)=[^&]+(&|$) [NC]

RewriteRule ^(.*)$ - [F,L]

但这里的问题是

http://example.com/search?query=test&debug=on&lang=en&foo=bar

即使黑客通过foo=bar,它也通过了,我想显示404,在到达php应用程序之前严格检查参数。

这里是:Rewrite Tester

没有显示 404

带有查询参数的有效网址示例

http://example.com/search?query=test&debug=on&lang=en

带有查询参数的无效网址示例

(检查是否有除允许的以外的任何查询参数???)

http://example.com/search?query=test&debug=on&lang=en&foo=bar
http://example.com/search?a=1
http://example.com/search?a=2
http://example.com/search?query=test&a=1

我可以在 php 中做同样的事情,但我想在到达我的 php 应用程序之前阻止请求。

$allowed = array('query', 'lang', 'debug');
foreach($_GET as $key => $value)
{
         if(!in_array($key, $allowed))
         {
                  http_response_code(403)  
                  die('Forbidden');
         }
}

也在我的网站上,请求 uri 允许的字符是 [A-Za-z0-9_-]

如果请求 uri 包含任何额外内容,我该如何阻止

也想知道,

  1. 是否也可以在重写时检查 POST 变量?
  2. 我看到很多可疑的代理字符串我该如何阻止它们
  3. 我还看到,在引用 url 黑客试图注入 xss 和 sqlinjection 字符串时,我该如何阻止它们。

【问题讨论】:

  • 你能发布一些你想拒绝/允许访问的 url 示例吗?
  • @starkeen : 示例http://example.com/search?query=test&debug=on&lang=en&foo=bar 无效,因为只允许lang,debug,query 查询参数,如果任何扫描器尝试这三个参数以外的其他参数,则应该得到 403
  • @starkeen:添加了更多描述

标签: mod-rewrite url-rewriting url-rewrite-module


【解决方案1】:

你可以用这个规则替换你现有的规则:

# Then parameters can be only query|debug|lang
# block any extra parameter
RewriteCond %{QUERY_STRING} ^(?!(?:query|debug|lang)=[^&]+(?:&(?:query|debug|lang)=[^&]+)*$). [NC]

RewriteRule ^ - [F]

如果 URL 中存在除 query|debug|lang 之外的任何查询参数,则此规则将返回 403

这里的(?!...) 是一个negative lookahead assertion,如果查询字符串除了给定参数之外还有其他内容,它将失败。


正则表达式详细信息:

  • ^:开始
  • (?!: 负前瞻开始
    • (?:query|debug|lang)=[^&]+:匹配 3 个允许的查询参数之一及其值
    • (?::启动非捕获组
      • &:匹配一个&
      • (?:query|debug|lang)=[^&]+:匹配 3 个允许的查询参数之一及其值
    • )*:结束非捕获组。 * 表示 0 或属于该组
    • $:结束
  • ): 否定前瞻表达式结束
  • .: 确保查询字符串不为空

简单来说,当查询字符串具有除 3 个允许参数之外的任何查询参数时,否定前瞻断言失败。

【讨论】:

  • 哦,你救了我,请你解释一下这个正则表达式^(?!(?:query|debug|lang)=[^&]+(?:&(?:query|debug|lang)=[^&]+)*$).,看起来现在我可以阻止一些扫描仪命中,另外我只想启用请求 uri 只能有 [A-Za-z0-9_-/] 但它阻止一些编码字符,我不确定,如何在请求 uri 中仅过滤掉安全字符
  • 非常感谢,如果您有时间,请指导我使用网络安全字符来请求 uri,目前我所有的 url 仅使用 [A-Za-z0-9_-/]+ 字符,但如何使用 % 处理编码字符?
  • 在字符类的最后一个字符处保留连字符以使其成为[\w/-]+。除了这些字符之外,所有其他特殊字符都不需要在那里
  • 先生,请您指导我post
【解决方案2】:

您可以使用以下内容:

RewriteEngine on

#if there is query string
RewriteCond %{QUERY_STRING} ^.+$
# Then parameters can be only query|debug|lang
# block any extra parameter
RewriteCond %{QUERY_STRING} !^(query|debug|lang)=[^&]+&(query|debug|lang)=[^&]+&(query|debug|lang)=[^&]+$ [NC]
RewriteRule .* - [F,L]

这将为不匹配 RewriteCond 正则表达式的 URL 返回 403 禁止错误。

【讨论】:

  • query=.+&debug=.+&lang 顺序不固定,可以在任何地方,例如http://example.com/search?debug=on&query=test&lang=en
  • @user3637224 我已经更新了模式。现在可以用了吗?
  • @user3637224 这就是您在帖子中提到的内容。您说有效的网址是 http://example.com/search?query=test&debug=on&lang=en 。该规则应该适用于该 URL。 /search?debug=on 是什么意思?这也是您有效网址的一部分吗?
  • 其实参数可以任意排列,允许有3个参数,可以是query或者lang或者debug或者三个都可以
  • @user3637224 您不能替换,而是将RewriteCond添加到现有的RewriteRule
猜你喜欢
  • 1970-01-01
  • 2011-07-07
  • 2021-03-23
  • 2013-11-12
  • 1970-01-01
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多