homepage Welcome to WebmasterWorld Guest from 54.145.243.51
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
mod rewrite: /foo but not /foo.php
Zuulo



 
Msg#: 4507342 posted 12:50 pm on Oct 12, 2012 (gmt 0)

Hello,
I hope you can help me with a little mod_rewrite issue. I have index.php and foo.php in my document root, but I need this behaviour:
example.com # 200
example.com/foo # 200
example.com/foo.php # 404

So it should not be possible to call the .php file directly.

I tried something like this, but now example.com/foo also responses with a 404.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ $1\.php [L]

RewriteCond %{REQUEST_URI} \.php$
RewriteRule ^(.*)$ - [L,R=404]


Can you help me?

Greetings,
Zuulo

 

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4507342 posted 8:18 pm on Oct 12, 2012 (gmt 0)

The REQUEST_URI pointer is modified (updated) by an internal rewrite.

Your rule that blocks access must test THE_REQUEST so that only external requests for .php are rejected.

The rule that blocks access must be listed before the internal rewrite rule.

If you omit the required leading slash before $1 in the rewrite, you leave your server wide open to "path injection" attacks.

Zuulo



 
Msg#: 4507342 posted 10:27 pm on Oct 12, 2012 (gmt 0)

Hi g1smd,
this seems to work fine now:

RewriteCond %{THE_REQUEST} \.php
RewriteRule ^(.*)$ - [L,R=404]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /$1\.php [L]


Do you have other improvements for this rewrite rule? I also added a leading slash before $1 (it's correct now, right?), but...I think I don't know well why this is necessary in this case. :(
Do you know a page, where the path injection problem without leading slash is explained?

Thank you very much,
Zuulo

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4507342 posted 10:59 pm on Oct 12, 2012 (gmt 0)

A few changes for efficiency...

The first
^(.*)$ should be \.php$

The second
^(.*)$ should be ^[^/.]+$ or ^([^/]+/)*[^/.]+$ and then the !-f test can be deleted.

The
/$1\.php should be /$1.php

[edited by: g1smd at 11:08 pm (utc) on Oct 12, 2012]

Zuulo



 
Msg#: 4507342 posted 11:03 pm on Oct 12, 2012 (gmt 0)

Ok, I've got another problem now. It's not working if someone trys example.com/bar and there is no bar.php file. Normally he should see a 404, but because of my last RewriteRule he will get an Internal Server Error. :(

So I think my solution isn't as good as I thought. Any idea to prevent this?

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4507342 posted 12:14 am on Oct 13, 2012 (gmt 0)

It's not working if someone trys example.com/bar and there is no bar.php file.

Your rule doesn't check whether bar.php exists. It only checks whether bar exists-- and you already know it doesn't, because filenames in this form never exist.

I would be doing (starting from scratch)

RewriteCond %{THE_REQUEST} \.php
RewriteRule ^([^.]*)\.php$ http://www.example.com/$1.php [R=301,L]

(I think this is what g1 says, but we overlapped in editing so I'm not sure)

and if they get the 301-to-404 sequence that's their tough luck for requesting a nonexistent page in the first place.

9 times out of 10, the !-f line seems to be the lazy way of dealing with entirely different requests such as .jpg or .css which should never make it to the Condition in the first place.

Note that you may need to make a few file-specific exemptions, for example in my case piwik.php, which lives in the same domain.

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4507342 posted 12:22 am on Oct 13, 2012 (gmt 0)

@lucy

^([^.]*)\.php$ allows blank filename. Replace * with + here.

Assume you'd want to redirect to extensionless. Either block or redirect. It doesn't matter either way if the .php URLs haven't been previously published.

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4507342 posted 1:55 am on Oct 13, 2012 (gmt 0)

Whoops, I did type too fast didn't I :)

Yup, REDIRECT to

blahblah-without-php

and then pair with a REWRITE to

blahblah-with-php

Ahem.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved