You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@httpd.apache.org by Roman Medina-Heigl Hernandez <ro...@rs-labs.com> on 2009/03/02 10:02:11 UTC
Re: [users@httpd] Mixing rewrite with authn_dbd: Rewriting based
on path value stored in mysql table
Hello,
I have a *partial*-working solution which I'd like to share with you. It's
tricky (based on my own home structure) and limited, though. Feedback is
appreciated, please!
Some comments:
- Debian 5.0 includes ajp 1.2.12, so I cannot get the url/dir from another
column in users' table (this functionality is for ajp 1.3+). In my case, I
can live without it, having the following convention: username will be a
domainname (which has sense, since I want to offer stats pages for
different domains). For instance, stats for domain "test.com" will use the
username "test.com".
- I've only experimented with per-dir rewrite (the non-recommended way...),
which has the limitation of request reinjection (so you must include
negative rewrite rules which protect you against loops). Perhaps it may be
improved with server rewrite.
- The current method is not secure: an attacker knowing the internal
homedir structure could easily craft a request bypassing the rewrite
ruleset, being able to access other domain/user's stats. It could also be
used to access other directories/files of other users (in my case those
dirs are protected using OS permissions).
- Performance is not very efficient, since I'm reinjecting requests (it
seems unavoidable if using per-dir rewrite).
- Stats home for domain "test.com" will be:
/clientes/test.com/stats/http/
which should be accessed through:
http://isp/stats/
Current config is:
====
Alias /stats /clientes
<Location /stats/>
# Basic Auth
AuthType Basic
AuthName "Stats"
AuthBasicProvider dbd
Require valid-user
AuthDBDUserPWQuery "SELECT pass FROM stats WHERE user = %s
and enabled = 1"
# Rewrite para que cada user entre a su directorio de stats
particular
RewriteEngine on
RewriteBase /stats
RewriteRule !^/clientes/[^/]+/stats/http/ - [C]
RewriteRule ^/clientes/(.*)
/stats/%{REMOTE_USER}/stats/http/$1 [PT]
====
More comments:
- at the beginning I tried something like:
RewriteBase /stats
RewriteCond $1 !^%{REMOTE_USER}/
RewriteRule ^/clientes/(.*)
/stats/%{REMOTE_USER}/stats/http/$1 [PT]
The problem is that you cannot have %{REMOTE_USER} as 2nd parameters in
RewriteCond, so I have no way for comparing it with $1 (which coudn't be in
2nd parameter, either). Any idea to implement it? (i.e. test if REMOTE_USER
string is included in URI path).
Cheers,
-Roman
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Mixing rewrite with authn_dbd: Rewriting based
on path value stored in mysql table
Posted by Roman Medina-Heigl Hernandez <ro...@rs-labs.com>.
Bob Ionescu escribió:
> 2009/5/12 Roman Medina-Heigl Hernandez <ro...@rs-labs.com>:
>> My final solution is:
>>
>> RewriteBase /stats
>> RewriteCond %{REMOTE_USER}/<>$1 !^([^<]+)<>\1
>> RewriteRule ^/clientes/(.*) /stats/%{REMOTE_USER}/stats/http/$1
>>
>> RewriteCond $1 !^[^/]+/stats/http/
>> RewriteRule ^/clientes/(.*) hacking_attempt [F]
>>
>>
>> The alternative (adding L) is:
>>
>> RewriteBase /stats
>> RewriteCond %{REMOTE_USER}/<>$1 !^([^<]+)<>\1
>> RewriteRule ^/clientes/(.*)
>> /stats/%{REMOTE_USER}/stats/http/$1 [L]
>>
>> RewriteCond $1 !^[^/]+/stats/http/
>> RewriteRule ^/clientes/(.*) hacking_attempt [F,L]
>>
>> But I see no real difference between both solutions. Am I right?
>
> L makes only sense to abort something below, i.e. if there's nothing,
> there's nothing to abort (F implies L btw., the substitution will be
> dropped as well). Your second rule (forbidden) comes never true, if
> the first rule matched. So you could stop further (useless) processing
> with the L flag at your first rule.
Agreed.
For the record, final solution:
RewriteBase /stats
RewriteCond %{REMOTE_USER}/<>$1 !^([^<]+)<>\1
RewriteRule ^/clientes/(.*)
/stats/%{REMOTE_USER}/stats/http/$1 [L]
RewriteCond $1 !^[^/]+/stats/http/
RewriteRule ^/clientes/(.*) hacking_attempt [F]
Thanks a lot to all who contributed the thread and specially to Bob!!!!
Cheers,
-Roman
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Mixing rewrite with authn_dbd: Rewriting based on
path value stored in mysql table
Posted by Bob Ionescu <bo...@googlemail.com>.
2009/5/12 Roman Medina-Heigl Hernandez <ro...@rs-labs.com>:
> My final solution is:
>
> RewriteBase /stats
> RewriteCond %{REMOTE_USER}/<>$1 !^([^<]+)<>\1
> RewriteRule ^/clientes/(.*) /stats/%{REMOTE_USER}/stats/http/$1
>
> RewriteCond $1 !^[^/]+/stats/http/
> RewriteRule ^/clientes/(.*) hacking_attempt [F]
>
>
> The alternative (adding L) is:
>
> RewriteBase /stats
> RewriteCond %{REMOTE_USER}/<>$1 !^([^<]+)<>\1
> RewriteRule ^/clientes/(.*)
> /stats/%{REMOTE_USER}/stats/http/$1 [L]
>
> RewriteCond $1 !^[^/]+/stats/http/
> RewriteRule ^/clientes/(.*) hacking_attempt [F,L]
>
> But I see no real difference between both solutions. Am I right?
L makes only sense to abort something below, i.e. if there's nothing,
there's nothing to abort (F implies L btw., the substitution will be
dropped as well). Your second rule (forbidden) comes never true, if
the first rule matched. So you could stop further (useless) processing
with the L flag at your first rule.
Bob
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Mixing rewrite with authn_dbd: Rewriting based
on path value stored in mysql table
Posted by Roman Medina-Heigl Hernandez <ro...@rs-labs.com>.
Bob Ionescu escribió:
> 2009/5/11 Roman Medina-Heigl Hernandez <ro...@rs-labs.com>:
>> Bob Ionescu escribió:
>>> 2009/3/2 Roman Medina-Heigl Hernandez <ro...@rs-labs.com>:
>>>> The problem is that you cannot have %{REMOTE_USER} as 2nd parameters in
>>>> RewriteCond, so I have no way for comparing it with $1
>>> -didn't read all-; but you can compare it with a regEx internal backreference.
>>>
>>> RewriteBase /stats
>>> RewriteCond %{REMOTE_USER}<>$1 !^([^<]+)<>\1
>> Could you explain that, please? I didn't know that syntax...
>
> You're capturing a value with ^([^<]+), that is according to our test
> string the value of %{REMOTE_USER} followed by the two characters <>
> as a unique separator followed by the (previous) match of ([^<]+)
> which matches against the value of $1.
>
> E.g. if the remote_user is foo, the regEx will match against a test string of
> foo<>foo
>
> Just take a look at the manpage of PCRE, http://www.pcre.org/pcre.txt section
> BACK REFERENCES
> Outside a character class, a backslash followed by a digit greater than
I knew (and have extensively used) about back references in PCRE but
thought the "<>" in RewriteCond's first arg could have a special meaning. I
didn't happen to figure out that you were simply "translating" REMOTE_USER
var to the second arg, using <> as separator. Nice trick!!!!!!
Anyway, I've fixed a bit by adding a slash character after REMOTE USER like
this:
RewriteCond %{REMOTE_USER}/<>$1 !^([^<]+)<>\1
(in order to avoid the bypass of the rewrite when you have authenticated as
"user" and the intruder is hacking/building URLs as "userrrrrrr").
>>> RewriteRule ^/clientes/(.*) /stats/%{REMOTE_USER}/stats/http/$1 [L]
>> Why did you removed PT and used L?
>
> PT has no special effect in per-directory context (rewrite rules used
> inside <directory>/<location> containers, .htaccess files etc.). In
> fact mod_rewrite will add passthrough: to the result of your
> substitution, stop the processing of following rules in that set and
> remove passthrough: later w/o doing sthg. special. L will only stop
> the rewrite of the current set. I.e. the result is the same.
I removed [L] (is it a good practice to keep it? if not, I don't see the
need to keep it) and added additional protection so the user could only
visit the desired (stats/http) directory (in order to avoid the user
including its own username in the url and reaching other directories in its
home).
My final solution is:
RewriteBase /stats
RewriteCond %{REMOTE_USER}/<>$1 !^([^<]+)<>\1
RewriteRule ^/clientes/(.*) /stats/%{REMOTE_USER}/stats/http/$1
RewriteCond $1 !^[^/]+/stats/http/
RewriteRule ^/clientes/(.*) hacking_attempt [F]
The alternative (adding L) is:
RewriteBase /stats
RewriteCond %{REMOTE_USER}/<>$1 !^([^<]+)<>\1
RewriteRule ^/clientes/(.*)
/stats/%{REMOTE_USER}/stats/http/$1 [L]
RewriteCond $1 !^[^/]+/stats/http/
RewriteRule ^/clientes/(.*) hacking_attempt [F,L]
But I see no real difference between both solutions. Am I right?
Cheers,
-Roman
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Mixing rewrite with authn_dbd: Rewriting based on
path value stored in mysql table
Posted by Bob Ionescu <bo...@googlemail.com>.
2009/5/11 Roman Medina-Heigl Hernandez <ro...@rs-labs.com>:
> Bob Ionescu escribió:
>> 2009/3/2 Roman Medina-Heigl Hernandez <ro...@rs-labs.com>:
>>> The problem is that you cannot have %{REMOTE_USER} as 2nd parameters in
>>> RewriteCond, so I have no way for comparing it with $1
>>
>> -didn't read all-; but you can compare it with a regEx internal backreference.
>>
>> RewriteBase /stats
>> RewriteCond %{REMOTE_USER}<>$1 !^([^<]+)<>\1
>
> Could you explain that, please? I didn't know that syntax...
You're capturing a value with ^([^<]+), that is according to our test
string the value of %{REMOTE_USER} followed by the two characters <>
as a unique separator followed by the (previous) match of ([^<]+)
which matches against the value of $1.
E.g. if the remote_user is foo, the regEx will match against a test string of
foo<>foo
Just take a look at the manpage of PCRE, http://www.pcre.org/pcre.txt section
BACK REFERENCES
Outside a character class, a backslash followed by a digit greater than
>> RewriteRule ^/clientes/(.*) /stats/%{REMOTE_USER}/stats/http/$1 [L]
>
> Why did you removed PT and used L?
PT has no special effect in per-directory context (rewrite rules used
inside <directory>/<location> containers, .htaccess files etc.). In
fact mod_rewrite will add passthrough: to the result of your
substitution, stop the processing of following rules in that set and
remove passthrough: later w/o doing sthg. special. L will only stop
the rewrite of the current set. I.e. the result is the same.
Bob
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Mixing rewrite with authn_dbd: Rewriting based
on path value stored in mysql table
Posted by Roman Medina-Heigl Hernandez <ro...@rs-labs.com>.
Bob Ionescu escribió:
> 2009/3/2 Roman Medina-Heigl Hernandez <ro...@rs-labs.com>:
>> More comments:
>> - at the beginning I tried something like:
>> RewriteBase /stats
>> RewriteCond $1 !^%{REMOTE_USER}/
>> RewriteRule ^/clientes/(.*)
>> /stats/%{REMOTE_USER}/stats/http/$1 [PT]
>>
>> The problem is that you cannot have %{REMOTE_USER} as 2nd parameters in
>> RewriteCond, so I have no way for comparing it with $1
>
> -didn't read all-; but you can compare it with a regEx internal backreference.
>
> RewriteBase /stats
> RewriteCond %{REMOTE_USER}<>$1 !^([^<]+)<>\1
Could you explain that, please? I didn't know that syntax...
> RewriteRule ^/clientes/(.*) /stats/%{REMOTE_USER}/stats/http/$1 [L]
Why did you removed PT and used L?
Wow!!!! I must say I'm frankly amazed, it seems it's working!! :-O But I'd
like to understand it in depth. Please, Bob, could you explain the trick to
me? :)))))
Thank you!!!
--
Saludos,
-Roman
PGP Fingerprint:
09BB EFCD 21ED 4E79 25FB 29E1 E47F 8A7D EAD5 6742
[Key ID: 0xEAD56742. Available at KeyServ]
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Mixing rewrite with authn_dbd: Rewriting based on
path value stored in mysql table
Posted by Bob Ionescu <bo...@googlemail.com>.
2009/3/2 Roman Medina-Heigl Hernandez <ro...@rs-labs.com>:
> More comments:
> - at the beginning I tried something like:
> RewriteBase /stats
> RewriteCond $1 !^%{REMOTE_USER}/
> RewriteRule ^/clientes/(.*)
> /stats/%{REMOTE_USER}/stats/http/$1 [PT]
>
> The problem is that you cannot have %{REMOTE_USER} as 2nd parameters in
> RewriteCond, so I have no way for comparing it with $1
-didn't read all-; but you can compare it with a regEx internal backreference.
RewriteBase /stats
RewriteCond %{REMOTE_USER}<>$1 !^([^<]+)<>\1
RewriteRule ^/clientes/(.*) /stats/%{REMOTE_USER}/stats/http/$1 [L]
Bob
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Mixing rewrite with authn_dbd: Rewriting based
on path value stored in mysql table
Posted by Roman Medina-Heigl Hernandez <ro...@rs-labs.com>.
Sorry for re-taking this thread... but I don't get to reach the right
solution... What I'd like to solve is the security problem stated below,
which could be exploited with something like:
https://XXX/stats/USER2/stats/http/YYYY
Since I'm comparing against:
!^/clientes/[^/]+/stats/http/
This would result in request not being rewritten at all, so authentication
would be easily bypassed with any existing user [user1, user2, user3, ...]
(when the desired behaviour should be only letting pass the one where "auth
user" == "user in url"). How could I enforce that?
Perhaps there's another (secure) way to mark the request as "rewritten", so
I could check later without the need to compare against
"!^/clientes/[^/]+/stats/http/".
Please, help! :-(
Cheers,
-r
Roman Medina-Heigl Hernandez escribió:
> Hello,
>
> I have a *partial*-working solution which I'd like to share with you. It's
> tricky (based on my own home structure) and limited, though. Feedback is
> appreciated, please!
>
> Some comments:
> - Debian 5.0 includes ajp 1.2.12, so I cannot get the url/dir from another
> column in users' table (this functionality is for ajp 1.3+). In my case, I
> can live without it, having the following convention: username will be a
> domainname (which has sense, since I want to offer stats pages for
> different domains). For instance, stats for domain "test.com" will use the
> username "test.com".
> - I've only experimented with per-dir rewrite (the non-recommended way...),
> which has the limitation of request reinjection (so you must include
> negative rewrite rules which protect you against loops). Perhaps it may be
> improved with server rewrite.
> - The current method is not secure: an attacker knowing the internal
> homedir structure could easily craft a request bypassing the rewrite
> ruleset, being able to access other domain/user's stats. It could also be
> used to access other directories/files of other users (in my case those
> dirs are protected using OS permissions).
> - Performance is not very efficient, since I'm reinjecting requests (it
> seems unavoidable if using per-dir rewrite).
> - Stats home for domain "test.com" will be:
> /clientes/test.com/stats/http/
> which should be accessed through:
> http://isp/stats/
>
>
> Current config is:
> ====
>
> Alias /stats /clientes
>
> <Location /stats/>
> # Basic Auth
> AuthType Basic
> AuthName "Stats"
> AuthBasicProvider dbd
>
> Require valid-user
> AuthDBDUserPWQuery "SELECT pass FROM stats WHERE user = %s
> and enabled = 1"
>
> # Rewrite para que cada user entre a su directorio de stats
> particular
> RewriteEngine on
> RewriteBase /stats
> RewriteRule !^/clientes/[^/]+/stats/http/ - [C]
> RewriteRule ^/clientes/(.*)
> /stats/%{REMOTE_USER}/stats/http/$1 [PT]
>
> ====
>
> More comments:
> - at the beginning I tried something like:
> RewriteBase /stats
> RewriteCond $1 !^%{REMOTE_USER}/
> RewriteRule ^/clientes/(.*)
> /stats/%{REMOTE_USER}/stats/http/$1 [PT]
>
> The problem is that you cannot have %{REMOTE_USER} as 2nd parameters in
> RewriteCond, so I have no way for comparing it with $1 (which coudn't be in
> 2nd parameter, either). Any idea to implement it? (i.e. test if REMOTE_USER
> string is included in URI path).
>
> Cheers,
> -Roman
>
> ---------------------------------------------------------------------
> The official User-To-User support forum of the Apache HTTP Server Project.
> See <URL:http://httpd.apache.org/userslist.html> for more info.
> To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
> " from the digest: users-digest-unsubscribe@httpd.apache.org
> For additional commands, e-mail: users-help@httpd.apache.org
>
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org