user2521224
user2521224

Reputation:

Apache - Deny access to all directories except public

I am developing a tool and I'm stuck at this point: I want to define a set of rules for each directory, basically I want only 'Public' folder avaible, and to deny access to other folders.

My directoy structure is

uapi(root)/
    Application
    Config
    Public/
         Index.php
    Storage
    .htaccess

and here is .htaccess file

<Directory /Public>
    Order Deny, Allow
    Allow from all
    <IfModule mod_rewrite.c>
        Options +FollowSymLinks
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ Index.php/$1 [L]
    </IfModule>
</Directory>

<Directory /Config>
    Order Deny, Allow
    Deny from all
</Directory>

<Directory /Application>
    Order Deny, Allow
    Deny from all
</Directory>

<Directory /Storage>
    Order Deny, Allow
    Deny from all
</Directory>

Upvotes: 4

Views: 21108

Answers (3)

Gus Calca
Gus Calca

Reputation: 121

For Apache httpd server 2.4 you can do that in this way:

In httpd.conf or in a .conf file in httpd/conf.d/ dir.

<Directory "/uapi/">
  Require all denied
</Directory>

<Directory "/uapi/public">
  Require all granted
</Directory>

I tested this config. The reference is here.

You should be able to do this in .htaccess files too, if you don't have access to the Apache config files. That would be, in /uapi/.htaccess:

Require all denied

and in /uapi/Public/.htaccess

Require all granted

As mentioned above, you can't use inside an .htaccess file. From Apache docs:

Note that unlike <Directory> and <Location> sections, <Files> sections can be used inside .htaccess files.

More general documentation: https://httpd.apache.org/docs/2.4/howto/access.html

Upvotes: 1

anubhava
anubhava

Reputation: 785176

You can do all that using mod_rewrite itself from your main DOCUMENT_ROOT/.htaccess file. Use this code:

Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /

RewriteRule ^(Application|Storage)(/.*|)$ - [NC,F]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^Public/(.*)$ /Public/Index.php/$1 [L,NC]

This code will throw Forbidden error for all the requests for /Storage/* or /Application/* but will let /Public/* be handled by /Public/index.php.

Upvotes: 2

Paolo Stefan
Paolo Stefan

Reputation: 10263

As this doc page says, you cannot use the <Directory> directive inside htaccess, but only inside server conf files.

This is not a problem in your case anyway: you can store one .htaccess file inside each directory, eg. create these files:

Public/.htaccess

Order Deny, Allow
Allow from all
<IfModule mod_rewrite.c>
    Options +FollowSymLinks
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ Index.php/$1 [L]
</IfModule>

/Config/.htaccess

Order Deny, Allow
Deny from all

/Application/.htaccess

Order Deny, Allow
Deny from all

/Storage/.htaccess

Order Deny, Allow
Deny from all

Upvotes: 7

Related Questions