在htaccess重写规则中将秘密令牌作为查询字符串追加的安全性如何? [英] How secure is to append a secret token as query string in a htaccess rewrite rule?
问题描述
我正在做一些测试,试图提供对 mod-rewrite的答案重定向但阻止直接访问.
I was doing some tests while trying to provide an answer to mod-rewrite redirect but prevent direct access.
最初的问题目标基本上是将
example.com/public/foo
屏蔽为example.com/foo
,同时禁止访问真实的URLexample.com/public/foo
.
Original question goal is basically mask
example.com/public/foo
asexample.com/foo
while forbidding access to the real URLexample.com/public/foo
.
一旦找到一种可能的解决方案,将 token 附加到重写的URL的查询字符串
Once I found a possible solution appending a token to the rewritten URL's Query String,
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)我真的在请求标题中看不到该令牌.
I realized (with Chrome's DevTools) that I really can't see this token in the Request Headers.
我知道这是因为第一个RewriteRule
不会触发客户端上的重定向,而所有这些重写过程都是在服务器上进行的.
I understand that's because the first RewriteRule
doesn't trigger a redirect on the client and all this rewrite process takes place in the server.
如果我是对的,那么此SECRET_TOKEN
是安全的,不是吗? (通过安全保护,我的意思是客户端无法以任何方式获知)
If I am right, this SECRET_TOKEN
is secure, isn't it? (By secure, I mean it can't be known by the client in any way)
推荐答案
通常,客户端永远都不会看到SECRET_TOKEN
-如您所说,重写是服务器内部的.
Ordinarily, the client should never see the SECRET_TOKEN
- as you say, the rewrite is internal to the server.
但是,根据服务器配置,SECRET_TOKEN
可能会在某些情况下被暴露.
However, it's possible the SECRET_TOKEN
could get exposed under certain conditions, depending on the server config.
例如,使用您发布的代码,通过请求example.com/public
或example.com/subdir
(其中subdir
是/public
内的子目录)可以暴露SECRET_TOKEN
-请注意省略了斜杠
For example, using the code you posted, the SECRET_TOKEN
could get exposed by requesting either example.com/public
or example.com/subdir
(where subdir
is a subdirectory inside /public
) - note the omission of the trailing slash.
-
example.com/public -如果要请求
/public
(不带斜杠),则mod_dir通过附加一个斜杠来纠正"此问题,这可以通过301实现外部重定向.但是,重定向不会立即发生,并且您的RewriteRule
指令最终会重写此请求(因为此时REQUEST_URI
变量仍为/public
-没有尾部斜杠)到/public/?token=SECRET_TOKEN
(请注意,现在尾部有斜杠)目录). (由于某些原因,URL路径似乎没有被RewriteRule
更新,因为您可能希望它是/public/public
,但是,查询字符串仍被附加.也许与mod_dir发出的子请求有关?不确定为什么?)由于mod_dir已触发301,因此此响应(包含SECRET_TOKEN
)现在作为外部重定向发送回用户,并且暴露了SECRET_TOKEN
.
example.com/public - If you were to request
/public
(no trailing slash) then mod_dir "corrects" this by appending a trailing slash, which is achieved with a 301 external redirect. However, the redirect does not occur immediately and yourRewriteRule
directive ends up rewriting this request (since theREQUEST_URI
variable is still/public
at this point - no trailing slash) to/public/?token=SECRET_TOKEN
(note the trailing slash now on the directory). (The URL-path does not appear to be updated by theRewriteRule
for some reason, as you might expect this to be/public/public
, however, the query string is still appended. Maybe something to do with the subrequest that mod_dir issues? Not sure why?) Since a 301 has already been triggered by mod_dir, this response (containing theSECRET_TOKEN
) is now sent back to the user as an external redirect and theSECRET_TOKEN
is exposed.
example.com/subdir -如果存在子目录/public/subdir
并且您请求了/subdir
(没有斜杠),则会发生类似(但略有不同)的情况.这次,您的RewriteRule
指令首先启动,并在内部将请求重写为/public/subdir?token=SECRET_TOKEN
.好的,到目前为止.但随后mod_dir插入,并想在/public/subdir
后面加上斜杠-它使用外部301重定向来完成此操作.因此,现在将请求重定向到/public/subdir/?token=SECRET_TOKEN
,并且SECRET_TOKEN
公开给用户(以及以前未知的/public
子目录).
example.com/subdir - A similar (but slightly different) thing would happen if there was a subdirectory /public/subdir
and you requested /subdir
(no trailing slash). Your RewriteRule
directive kicks in first this time and internally rewrites the request to /public/subdir?token=SECRET_TOKEN
. Ok so far. But then mod_dir kicks in and wants to append a trailing slash to /public/subdir
- it does this with an external 301 redirect. So the request is now redirected to /public/subdir/?token=SECRET_TOKEN
and the SECRET_TOKEN
is exposed to the user (as well as the /public
subdirectory, which was previously unknown).
但是,以这种方式使用查询字符串确实有一些其他警告:
However, using the query string in this way does have some other caveats:
-
按现状,您正在覆盖请求上的任何其他查询字符串.
As it stands, you are overwriting any other query string on the request.
要在请求上合并现有查询字符串,您需要在RewriteRule
上指定QSA
标志.但是,如果用户随后在请求上附加了?token=
,则如果您想在PHP脚本中使用$_GET
超全局变量来读取token
URL参数,则他们将覆盖您的token
URL参数.您可以通过将QUERY_STRING
服务器变量显式包含在 substitution 中而不是使用QSA标志来手动更改查询字符串参数的顺序-但这会更加混乱(例如,如果出现这种情况,该怎么办)没有查询字符串吗?).
To merge an existing query string on the request, you would need to specify the QSA
flag on the RewriteRule
. However, if a user then appended ?token=
on the request then they would override your token
URL param if you wanted to read this using the $_GET
superglobal in a PHP script. You could manually change the order of the query string parameters by explicitly including the QUERY_STRING
server variable in the substitution instead of using the QSA flag - but this is a bit more messy (eg. what if there is no query string?).
这篇关于在htaccess重写规则中将秘密令牌作为查询字符串追加的安全性如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!