views:

17

answers:

1

Hello, I am trying to achieve the following through mod_rewrite:

1. What is the basic directory structure?

  • /
    • main/ (folder)
      • a bunch of PHP files
    • some_folder/ (folder)
    • another_folder/ (folder)
    • ... (an arbitrary number of such folders)
    • yet_another_folder/ (folder)
    • .htaccess(the magic goes here)

2. What I am trying to do?

In this scenario all the executable files are contained in the main folder and they should be accessed only through the additional folders. Moreover, the PHP scripts rely on an apache environment variable to pass them some information, which is related to the name of the folder through which they are accessed. Another special requirement is that the main folder should not be accessible directly (only through an internal redirect).

3. How far did I get?

I implemented the following .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(main|another)/.*$
RewriteRule ^(.*)/(.*)$ /main/$2 [QSA,L,env=VAR_NAME:$1/weird_include.php]

It generally does the redirect, however there are some issues...

4. What is the big deal?

Using this approach, the main (and the anotheras well) folder can still be accessed directly, and I want it to be accessible only through one of the auxiliary folders. The second problem is that, because there is a rewrite, the mod_rewrite adds a REDIRECT_ prefix to the variables and since I have completely no control over the source code residing in main and it requires specific variable names, that doesn't work for me at all. Also I haven't found a decent way yet to isolate the access to main and other-main folders...

5. Where I believe the key to the tent is?

This post in the PHP doc on the topic suggests adding a rule similar to this one
RewriteRule ^index\.php$ \ - [E=VAR1:%{REDIRECT_VAR1},E=VAR2:%{REDIRECT_VAR2},L]
would resolve the issue. However I don't see how I can modify that to conform to the 'no direct access' requirement. And also - what overhead does mod_rewrite introduce? The other important question would be how to restrict the access to main and other-main in the forementioned way?
Would adding a .htaccess file in these two folders, that does checks for REDIRECT_VAR_NAME1 and if it is present, rewrites it to VAR_NAME, leaving the url intact, and if it is not redirects to 403 forbidden do the trick? And also any hint towards what the overhead of this would be greatly appreciated.

+1  A: 

If the scripts in /main/ absolutely require that environmental variable have particular names, and if you can't change the environment variables, use the auto_prepend_file directive in php.ini to include a particular PHP file at the beginning of every PHP script. This would allow you to pre-process environment variables without actually modifying any other file.

For example, if you want FOO but you're stuck with REDIRECT_FOO, put the following line in whatever PHP file you've designated as auto_prepend. This will reassign REDIRECT_FOO to FOO. The script that gets executed afterwords wouldn't have a clue what happened.

$_ENV['FOO'] = $_ENV['REDIRECT_FOO'];

On your other question, yes, rewriting everything like that adds a bit of overhead, but I'm not sure how much. It's probably negligible compared to whatever your PHP script is doing.

To prevent direct access to /main/, put the following in your .htaccess file.

<Location /main/>
    Order deny,allow
    Deny from all
</Location>

BTW, if you have any control over the scripts themselves, fix them instead of relying on hacks like this.

kijin