views:

346

answers:

6

Here's my .htaccess file:

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* ?p=$0

Which should redirect to mysite.com/?p=request only if request is not a file. But, it's improperly matching a request like http://mysite.com/auth.php?openid.ns=http%3A%2F because of the %2F (auth.php does exist). I don't understand why that's screwing things up... ideas?

Edit: Guys, I put emphasis on %2F (which is a forward slash btw) because it works fine when this character isn't in there

To be clear,

I get a 404 for this page: http://mysite.com/auth.php?openid.ns=http%3A%2F

but not this page: http://mysite.com/auth.php?openid.ns=http%3A


Just FYI, I really screwed this question up. It was a 403 error that occurred anytime %2F appeared in the URL. My app was catching this error and spitting out a deceptive 404 which might be less frightening to the end user. Really had nothing to do with .htaccess after all. More details in my answer below.

A: 

can you make sure you don't mean this?

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -f

to test what the value of the variable is, use something like:

RewriteRule (.*) http://www.google.com/?test=%{REQUEST_FILENAME} [L]

if it doesn't have the full filepath to your auth.php file, it won't find it. i got this info here:

http://mail-archives.apache.org/mod_mbox/httpd-bugs/200812.mbox/

ifatree
%{REQUEST_FILENAME} spits out the full filename, /home/username/public_html/mysite/auth
Mark
A: 

It's probably related to the fact that you don't have parentheses in your regex so capturing does not happen. The following works for me:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ ?p=$1 [L,QSA]
Ayman Hourieh
Sure it happens; $0 is the whole thing. Tested to make sure.
Mark
+3  A: 

Is it possible you need to enable AllowEncodedSlashes, which is off by default? When this directive is switched off, requests containing encoded forward and back slash characters (i.e. %2F and %5C) are refused with a 404.

I vaguely remembered seeing this issue in MediaWiki, where all sorts of fun things have to be done when escaping titles and so on, to avoid the various cock-ups at different levels of request handling. Turns out, quite a lot of things in Apache land like to mess around with PATH_INFO and suchlike, which causes no end of hell for the rest of us.

Rob
This does sound like it could be the problem, but when enabling AllowEncodedSlashes it gives me a 500 internal server error, even with *no* rewrite rules :(
Mark
Check the Apache error log; what is the "internal error" that's occurring? That might provide some hint. I'd also second kch's advice above; enable verbose rewrite logging and take a look at the log output from a failed request to see what actually happens. http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritelog contains information on how to enable rewrite logging.
Rob
Using RewriteLog gives me an internal server error too... my best guess is that the admins disabled it. Can't check the apache error log without contacting the admins either. I'll go whine at them and see what they have to say.
Mark
Yep... hostgator doesn't allow it. I'm submitting a ticket... is there anything "dangerous" about AllowEncodedSlashes?
Mark
Host supposedly enabled it for me, but I still get the same error... is there anything else it could be?
Mark
I'm afraid I don't have any other ideas at the moment; it was purely a flash across the synapses that led me to double-check the issue.
Rob
A: 

Wasn't a AllowEncodedSlashes problem. It was hitting a mod_security rule that forbid http:// in the params to prevent file injection. They whitelisted it for me.

Mark
A: 

glad you got it figured out with your hosting provider. did you find other slash combinations that worked and confront them about it? ;)

a non-apache-related answer would be to not pass the known "http://" string in the parameter at all. looking at my stackoverflow account page as an openID example, it doesn't even seem to store "http://" at all, just "me.yahoo.com/a/swxth....".

maybe that's the real answer. if you app expects to do something internally with an "http" URL, it should know to add it to the beginning at the last responsible moment.

ifatree
Yes, except my web app isn't generating these URLs. They're coming from Google and Yahoo! and such; I'm trying to implement OpenID support like StackOverflow does. Almost done now :)
Mark
A: 

Did you resolve the issues you Were having? I am also trying to implement openid.

Yes, I did. Are you on a shared host? I was hitting a `mod_security` rule that forbid `http://` from being in the params to prevent injection. If this is the case for you, get the server admin to whitelist it for you.
Mark