Search code examples
apache.htaccesshttp-redirectmod-rewritehttp-status-code-403

.htaccess - Limit access to files unless accessed by server


I'm looking for help with .htaccess rewrite rules for my server.

Considering I have the following structure:

index.html
foo.html
private\
        bar.js
        secret.txt
public\
       helloworld.js
       cat.jpg

I need the following conditions:

  1. Users navigating to http://example.com, http://example.com/index.html, http://example.com/foo.html or http://example.com/foo should be able to load up without issue.
  2. Users navigating to http://example.com/private/bar.js or http://example.com/private/secret.txt and any other file in this folder should get a 403 forbidden, although these files should be able to be accessed by the html files which use it.
  3. Users navigating to http://example.com/public/ should be able to access anything in there.

The last point is just for me to understand how I could negate the rule if needed. I managed to get somewhere by blocking files unless they were .html but it didn't work for when the extension was omitted and it was very messy so I'm hoping some pros could help me out with a clean way of doing this.

EDIT: Clarified requirement #2 to include all files in the private folder


Solution

  • Based on your shown samples, could you please try following. Please make sure you clear your browser cache before testing your URLs. Basically its for 2nd condition. Your 3rd condition anyways doesn't needs any rule(considering that you don't have any other rules for public folder as per 3rd condition).

    RewriteEngine ON
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^private/(bar\.js|secret\.txt)/?$ - [R=403,L]
    


    2nd solution: Make sure either you use above OR following rules only at a time, following considers that you want to allow only http://example.com, index.html, foo.html OR foo URLs as per your first condition and block others if this is the case then one could try following.

    RewriteEngine ON
    ##In case you want to forbid anything apart from:
    ##http://example.com, index.html, foo.html OR foo then following.
    RewriteCond ^(index\.html|foo\.html|foo)/?$ [NC]
    RewriteRule ^ - [R=403,L]
    
    ##For forbidding private/bar.js and private/secret.txt here.
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^private/(bar\.js|secret\.txt)/?$ - [R=403,L]