tags:

views:

1870

answers:

5

I want to deny direct access to all .php files except one: index.php

The only access to the other .php files should be through php include.

If possible I want all files in same folder.

UPDATE:

A general rule would be nice, so I don't need to go through all files. The risk is that I forget a file or line.

UPDATE 2:

The index.php is in a folder www.myadress.com/myfolder/index.php

I want to deny access to all .php files in myfolder and subfolder to that folder.

+4  A: 

You can try defining a constant in index.php and add something like

if (!defined("YOUR_CONSTANT")) die('No direct access');

to the beginning of the other files.

OR, you can use modrewrite and redirect requests to index.php, editing .htaccess like this:

RewriteEngine on
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ /index.php/$1 [L]

Then you should be able to analyze all incoming requests in the index.php and take according actions.

If you want to leave out all *.jpg, *.gif, *.css and *.png files, for example, then you should edit second line like this:

RewriteCond $1 !^(index\.php|*\.jpg|*\.gif|*\.css|*\.png)
n1313
You might want to update the filter for only .php files
Swanand
Do you know how? I have no clue.
Johan
I've added a howto for this.
n1313
Does it matter that index.php is in a folder.
Johan
Yes, you should write full absolute path to it in RewriteRule, like RewriteRule ^(.*)$ /somedir/anotherdir/index.php/$1 [L]
n1313
+1  A: 

In index.php, add an access value like this:

$access = 'my_value';

In every other file, include this check before even a single byte is echoed out by php:

if (empty($access)) {header("location:index.php");}

This way, other php files will be accessible only through require / include and not through the url.

Crimson
You also need to have a `exit();` or `die();` after `header()`, otherwise execution will continue as normally.
nikc
+5  A: 

Are you sure, you want to do that? Even css and js files and images and ...?

OK, first check if mod_access in installed to apache, then add the following to your .htaccess:

Order Deny,Allow
Deny from all
Allow from 127.0.0.1

<Files /index.php>
    Order Allow,Deny
    Allow from all
</Files>

The first directive forbids access to any files except from localhost, because of Order Deny,Allow, Allow gets applied later, the second directive only affects index.php.

Caveat: No space after the comma in the Order line.

[EDIT:]

To allow access to files matching *.css or *.js use this directive:

<FilesMatch "*\.(css|js)$">
    Order Allow,Deny
    Allow from all
</FilesMatch>

You cannot use directives for <Location> or <Directory> inside .htaccess files, though.

Your option would be to use <FilesMatch "*\.php$"> around the first allow,deny group and then explicitely allow access to index.php.

Residuum
Hmm... no, only for .php-files
Johan
Ok, I'm totally novice to .htaccess I tried to copypaste your code, and it works to deny all files except index.php, but not to allow non .php-files. Here is my .htaccess-file:Order Deny,AllowDeny from allAllow from 127.0.0.1<Files index.php> Order Allow,Deny Allow from all</Files><FilesMatch "*\.(css|js)$"> Order Allow,Deny Allow from all</FilesMatch>
Johan
+1  A: 

How about keeping all .php-files except for index.php above the web root? No need for any rewrite rules or programmatic kludges.

Adding the includes-folder to your include path will then help to keep things simple, no need to use absolute paths etc.

nikc
Ok, I move my files to another folder. Thanks for all .htaccess help, but it was to complicated for me.
Johan
Or maybe not, it was too many linkreferences between my documents so I wait with this solution.
Johan
What do you mean by linkreference? Did you add the folder you moved the files to into your include path?
nikc
Linkreference = `include('file.php')` to `include('myfolder/file.php')`
Johan
If you include the folder you move the files into in your include path (`ini_set('include_path', ini_get('include_pat'). ':/path/to/files');`), then you can do the same thing without anything breaking.
nikc
A: 

An oblique answer to the question is to write all the code as classes, apart from the index.php files, which are then the only points of entry. PHP files that contain classes will not cause anything to happen, even if they are invoked directly through Apache.

A direct answer is to include the following in .htaccess:

<FilesMatch "\.php$">
    Order Allow,Deny
    Deny from all
</FilesMatch>
<FilesMatch "index[0-9]?\.php$">
    Order Allow,Deny
    Allow from all
</FilesMatch>

This will allow any file like index.php, index2.php etc to be accessed, but will refuse access of any kind to other .php files. It will not affect other file types.