问题
I was doing some tests while trying to provide an answer to mod-rewrite redirect but prevent direct access.
Original question goal is basically mask
example.com/public/fooasexample.com/foowhile forbidding access to the real URLexample.com/public/foo.
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]
I realized (with Chrome's DevTools) that I really can't see this token in the Request Headers.
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.
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)
回答1:
Ordinarily, the client should never see the SECRET_TOKEN - as you say, the rewrite is internal to the server.
However, it's possible the SECRET_TOKEN could get exposed under certain conditions, depending on the server config.
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 - 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 yourRewriteRuledirective ends up rewriting this request (since theREQUEST_URIvariable is still/publicat 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 theRewriteRulefor 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_TOKENis exposed.example.com/subdir - A similar (but slightly different) thing would happen if there was a subdirectory
/public/subdirand you requested/subdir(no trailing slash). YourRewriteRuledirective 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_TOKENand theSECRET_TOKENis exposed to the user (as well as the/publicsubdirectory, 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.
To merge an existing query string on the request, you would need to specify the
QSAflag on theRewriteRule. However, if a user then appended?token=on the request then they would override yourtokenURL param if you wanted to read this using the$_GETsuperglobal in a PHP script. You could manually change the order of the query string parameters by explicitly including theQUERY_STRINGserver 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?).
来源:https://stackoverflow.com/questions/45333170/how-secure-is-to-append-a-secret-token-as-query-string-in-a-htaccess-rewrite-rul