Block access to files and sub directory with .htaccess? - php

I have nearly 30 php files, 4 sub directories in my directory. I want to block some php files and sub directories from user in direct viewing like http://bhavani.com/hai.php
My currect htaccess file
## Enable Mod Rewrite, this is only required once in each .htaccess file
RewriteEngine On
RewriteBase /
## Test for access to includes directory
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /includes/ .*$ [NC]
## Test that file requested has php extension
RewriteCond %{REQUEST_FILENAME} ^.+\.php$
## Forbid Access
RewriteRule .* - [F,NS,L]
How to do it?

You can filter the files like this
<Files ~ "\.php$">
Deny from all
</Files>
And directory like this
<Directory "/subdirectory">
Deny from all
</Directory>

You don't need mod_rewrite to accomplish this. A much simpler way of doing this would be with RedirectMatch directive from mod_alias:
RedirectMatch 403 ^.*/include/*\.php$
This will automatically respond with 403 Forbidden to a direct request for any PHP file inside include subdirectory, however you would still be able to include them from inside other php files.

I think you can use only RewriteRule without RewriteCond
For example:
RewriteRule ^/hai\.php - [F, NS, L]
This rule forbid access to file hai.php
For other files you can use other Rule or use mask.

Related

htaccess - Redirect to error page if user attempts direct file access?

I have a website where the main directory contains a few files i don't want to be directly accessed using urls like this:
http://website.com/somefile1.ext1
http://website.com/somefile2.ext1
http://website.com/somefile1.ext2
http://website.com/somefile2.ext2
Currently they download if you enter the urls in a browser. Instead i would like to redirect them to a error page like this:
http://website.com/404
I found this snippet online but it doesn't work, it also doesn't redirect:
<Files ~ "\.(ext1)$">
Order allow,deny
Deny from all
</Files>
What would the correct .htaccess code be to do this task?
Edit:
I redirect site.com/script.php etc to site.com/script with this code:
RewriteEngine On
# turn on the mod_rewrite engine
RewriteCond %{REQUEST_FILENAME}.php -f
# IF the request filename with .php extension is a file which exists
RewriteCond %{REQUEST_URI} !/$
# AND the request is not for a directory
RewriteRule (.*) $1\.php [L]
# redirect to the php script with the requested filename
Try it like this I didn't tried it for now,
RewriteEngine On
RewriteCond %{REQUEST_URI} \.ext\d$
RewriteRule ^ 404 [R=301]
Try
<FilesMatch "somefile\.ext$">
Deny from all
</FilesMatch>
You don't need to use the Order directive if you want to deny access from all.

htaccess to allow only visits from ip but whitelist a dir and a file?

I want to add a htaccess to allow visits from a specific ip.
The tree goes like this
domain
/abc/
/def/
I want to restrict the folder /abc/ but whitelist the folder /def/
Also, on the /abc/ there is a specific file called ghi.php. Can I allow access to that specific file ?
How can I do this?
This is what i have in /abc/ that redirects everyone who is not into the specified ip. However, I want to allow access to the ghi.php inside that dir.
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^125\.17\.119\.16$
RewriteRule ^ http://www.domain.com/ [R]
I would not use mod_rewrite for content protection, use the modules that are created for this:
# Default: deny all
Order Allow,Deny
# Allow the IP for everything
Allow from 125.17.119.16
# Allow access to this one PHP file
<Files /abc/ghi.php>
Allow from all
</Files>
# Allow access to everything inside that folder
<FilesMatch "^/def/">
Allow from all
</FilesMatch>
Try :
RewriteEngine on
#Allow access to the file
RewriteRule ^abc/ghi\.php$ - [L]
#forbid the request for /abc/* if ip not=1.2.3.4.5
RewriteCond %{REMOTE_ADDR} !^1\.2\.3\.4\.5$
RewriteRule ^abc - [F,L]
If you want to redirect the request to homepage, just change the line
RewriteRule ^abc - [F,L]
to
RewriteRule ^abc http://example.com/ [L,R]

htaccess: how to forward a request to a forbidden folder?

desired:
user calls domain.tld/download/file_01.zip
htaccess calls private/download.php
file_01.zip starts to download
Note: file_01.zip must be protected from direct access.
Simplified folder structure:
root/
public/
.htaccess
index.php
private/ <<< this area is blocked from direct access >>>
files/
file_01.zip
file_02.zip
.htaccess
download.php
public/.htaccess
RewriteRule ^download/(.*)?$ ./../private/download.php?file=$1 [NC,L]
private/.htaccess (Edit)
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
download.php
$file = 'files/'.$_GET['file'];
// check: user allowed to download?
// check: more stuff (security, etc.) ...
forceDownload($file);
The RewriteRule works, but I'm getting the error Forbidden: You don't have permission to access [...] on this server, probably because the user calls the request, not the server.
Any idea?
Thanks in advance!
There is one more approach. Rename particular directory (add a single dot before it's current name, .private for example) and place this inside .htaccess file.
RewriteRule (^\.|/\.) - [F]
After adding this rule, each and every file and directory that begins with one . will be forbidden/protected, just like .htaccess it self is. :)
This will prevent access to anyone but PHP to open, view, modify file/dir contents.
Here is sample of (very common I believe) basic .htaccess *(sitting in DOCUMENT_ROOT directory) mod_rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule (^\.|/\.) - [F]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)$ /$1.php [QSA,L]
</IfModule>
Once that this is being done, You don't serve direct links to .zip or whichever file ext. You have in mind, but do that in some other fashion with favorite PHP 'tricks' of Yours. :)
If You feel that this will give You a lot of code refactoring, just because one directory, You can add those dots to zip files, and move them elsewhere, direct access to dotted files, still won't be possible.
As RiggsFolly stated in their comment.
You need to modify that private/ .htaccess file to something like:
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
Allow from 127.0.0.1 #or your server address/etc
</IfModule>
Here is another solution, giving that your Apache version is >=2.4. (via using Require)
<IfModule !mod_authz_core.c>
Require all granted
Require ip 127.0.0.1
</IfModule>

Preventing access to include files

I'm having a problem with .htaccess file rewrite rules. I want to have one .htaccess file in my root directory and to have rule over there to stop people to be able to access files directly over browser. So, for example I have folder blah/includes/file.php and .htaccess file is in blah/ folder, I want to prevent people to be able to just type in browser blah/includes/file.php and get that file, but also I want my functions in app to be able to use those files. I understand that is almost impossible for them to know exact name of my include files but I would like to be sure.
Thanks in advance.
here is my code which is not responding:
<IfModule mod_rewrite.c>
## Enable Mod Rewrite, this is only required once in each .htaccess file
RewriteEngine On
RewriteBase /
## Test for access to includes directory
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /includes/ .*$ [NC]
## Test that file requested has php extension
RewriteCond %{REQUEST_FILENAME} ^.+\.php$
## Forbid Access
RewriteRule .* - [F,NS,L]
</IfModule>
Note: I'm testing in localhost if that is maybe important.
Problem is in the first RewriteCond you have a space after /includes/, which throws an error.
BUT: I wouldn't use %{THE_REQUEST}, as it contains the HTTP Request (see http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritecond). Use %{REQUEST_URI} instead.
So, if you want to forbid access to /<folder>/include/*.php, you can use just this code:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/[^/]+/includes/.*\.php$ [NC]
RewriteRule .* - [F,NS,L]
</IfModule>
Assuming your .htaccess lies in the blah/ folder.
The quickest way would be just to put a one-line .htaccess file in your includes directory:
deny from all
The other alternative is to place your includes folder outside of your web-accessible directory.
/home/
/username/
/includes/
/public_html/
/index.php
If you still want to use a RewriteRule, then this is the one you’d use:
RewriteRule ^includes/ - [F,L,NC]
Which would return a 401 Forbidden response trying to access a URI that begin with includes.

Using index.php to manage all url paths in my site

I must be missing something obvious, since this seems like it shouldn't be a difficult problem. I want all url paths on my site (http://example.com, http://example.com/admin, http://example.com/happy/happy/joy/joy, etc.) to be handled through my index.php. I've seen this done before, but offhand I do not know how to do it.
Just create an .htaccess file in your root directory with this :
# Turn on URL rewriting
RewriteEngine On
# Base directory
RewriteBase /
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php/$0 [PT]
Apache flags explained :
[L] - Alias for "Last", instructs the server that the rewrite rules have come to an end and it's time to perform an internal redirection without changing the browser's uri.
[PT] - Alias for "Pass Through", allows a Mod_Rewrite manipulated uri to be passed to the next type of handler, accordingly to the php.ini module's order of inclusion. Usefull depending on the subject.

Categories