在htaccess重写规则中将秘密令牌作为查询字符串附加是否安全?

时间:2017-07-26 16:57:39

标签: apache .htaccess security mod-rewrite token

在尝试提供mod-rewrite redirect but prevent direct access的答案时,我正在做一些测试。

  

原始问题目标基本上是example.com/public/foo example.com/foo,同时禁止访问真实网址example.com/public/foo

我找到一个可能的解决方案,将令牌附加到重写的URL的查询字符串中,

RewriteCond %{REQUEST_URI} !/public/
RewriteRule ^(.*)$ /public/$1?token=SECRET_TOKEN [L]

RewriteCond %{REQUEST_URI} /public/
RewriteCond %{QUERY_STRING} !token=SECRET_TOKEN
RewriteRule ^(.*)$ / [R=403,L]

我意识到(使用Chrome的DevTools)我真的无法在请求标题中看到此标记。

Headers Screenshot

我理解这是因为第一个RewriteRule没有触发客户端上的重定向,所有这些重写过程都发生在服务器中。

如果我是对的,这SECRET_TOKEN是安全的,不是吗? (安全,我的意思是客户无法以任何方式知道)

1 个答案:

答案 0 :(得分:2)

通常,客户端永远不会看到SECRET_TOKEN - 如您所说,重写是服务器内部的。

但是,SECRET_TOKEN可能会在某些条件下暴露,具体取决于服务器配置。

例如,使用您发布的代码,SECRET_TOKEN可以通过请求example.com/publicexample.com/subdir(其中subdir/public内的子目录来公开/public }) - 注意遗漏斜杠。

  1. example.com/public - 如果您要请求RewriteRule(没有尾部斜杠),则mod_dir通过附加一个尾部斜杠来“纠正”这个,这是通过301外部重定向。但是,重定向不会立即发生,并且您的REQUEST_URI指令最终会重写此请求(因为此时/public变量仍然是/public/?token=SECRET_TOKEN - 没有尾随斜杠)到{{1} (注意目录上的尾部斜杠)。 (由于某些原因,RewriteRule似乎没有更新URL路径,因为您可能会认为这是/public/public,但是,查询字符串仍然被追加。可能与mod_dir发出的子请求?不确定原因?)由于mod_dir已经触发了301,因此该响应(包含SECRET_TOKEN)现在作为外部重定向发送回用户<{1}}已曝光。

  2. example.com/subdir - 如果存在子目录SECRET_TOKEN并且您请求/public/subdir(没有尾随),则会发生类似(但略有不同)的事情削减)。您的/subdir指令首次启动,并在内部将请求重写为RewriteRule。好到目前为止。但是然后mod_dir启动并希望在/public/subdir?token=SECRET_TOKEN附加一个尾部斜杠 - 它使用外部301重定向执行此操作。因此,请求现在重定向/public/subdir/public/subdir/?token=SECRET_TOKEN向用户(以及之前未知的SECRET_TOKEN子目录公开)。< / p>

  3. 但是,以这种方式使用查询字符串确实有一些其他注意事项:

    1. 目前,您正在覆盖请求中的任何其他查询字符串。

    2. 要合并请求中的现有查询字符串,您需要在/public上指定QSA标记。但是,如果用户随后在请求中附加了RewriteRule,那么如果您想在PHP脚本中使用?token=超全局读取它,那么他们将覆盖您的token URL参数。您可以通过在替换中明确包含$_GET服务器变量而不是使用QSA标志来手动更改查询字符串参数的顺序 - 但这有点混乱(例如,什么如果没有查询字符串?)。