Question

I'm using CodeIgniter and I added some rules in .htaccess to redirect all requests to index.php/a/b to /a/b These are the rules:

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

I want to disable directory listing in apache, so I added the following rule:

Options -Indexes

The problem is that once I added this rule, it disables directory listing but also redirects any call to a specific folder (that doesn't contains an index.* file) to a CodeIgniter Controller (which doesn't exists, and generates a 404 error).

Before: access to a /X folder would return a directory listing

After: access to a /X folder would call index.php/X silently and return a 404 error.

I want that any access to /X and any subfolder in it simply return a 403 forbidden error (or any error that doesn't involve running a php script), not call index.php/X (I want to users to be able to access files in /X and its subfolders, but not allow users to see a directory listing of /X and its subfolders).

I have tried, without success:

  • adding a <Directory "/X"> rule. Looks like i can't use it in my .htaccess
  • adding a RewriteCond $1 !^(X.*|/X.*) rule before RewriteRule ^(.*)$ index.php/$1 [L] (see above). It doesn't seem to work.

What should I write in .htaccess to solve this problem ?

Was it helpful?

Solution

To exclude any folder starting with /X use the added #1 ReWriteCond below.

To return a 403 for /X and sub-directories, uncomment the two lines following #1, and comment the line following #2. Order is important, so this rule must come first if you want it to work

RewriteEngine On
RewriteBase /

#1 to return a 403, for /X, uncomment these 2 lines
#RewriteCond %{REQUEST_URI} ^/X [NC]
#RewriteRule . - [L,F]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#2 exclude any folder starting with X
RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ /X [NC]
RewriteRule ^(.*)$ index.php/$1 [L]

OTHER TIPS

You cannot use <Directory /X> in a .htaccess because a .htaccess is a <Directory> instruction, exported outside of the apache compiled configuration, and checked at runtime for every request. yes .htaccess is bad and performs very slow, but that also mean you could remove all your .htaccess and replace it with the right <Directory> things in the apache configuration files if you have access to such files.

Now your problem. You want to detect directaccess to a directory, /X, and send an http error code for that. To extend this rule to all directories /foo or /foo/bar which do not contains index.php files I would simply write:

# detect requested url IS a directory
RewriteCond %{REQUEST_FILENAME} -d
# detect the requested directory does not contain an index.php file
RewriteCond %{REQUEST_FILENAME}index.php !-f
# then bail out
RewriteRule ^(.*)$ - [R=403,L]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top