Here's my .htaccess
<Files *>
Order Deny,Allow
Deny from all
</Files>
<Files index.php>
Order Deny,Allow
Allow from all
</Files>
This is not working, cause if I type the hostname in my browser, it serves the index.php but apache doesn't seem to apply the Files instructions and instead returns a non-allowed file access page, I need typing the fullname document (e.g. 'index.php') to make it work. which is not really convenient...
how to proceed if I want users only access index files of each folder in my website ?
all the other files are just script inclusions so i believe i'm doing right trying to make them inaccessible from the web (or maybe not, if only you have one reason to prove the other case).
Regardless the question above, is it the right way to do the job ? (I think the two directives here are not neat but it's the only way, well almost the only way that I know to avoid accesses to files).
Not exactly sure why you need to do this, but you can use mod_setenvif (no need to wrap this inside a <Files>)
SetEnvIf Request_URI ^/index.php$ index
Order Allow,Deny
Allow from env=index
This will cause access to hostname.com/ to 403 but allow hostname.com/index.php. If you want to allow / as well, just add
SetEnvIf Request_URI ^/$ index
to the top. Of course, all this will make it so anything that index.php links to will also return a 403.
<Files *?>
Order deny,allow
Deny from all
</Files>
You just need to add a question mark to match at least one character.
Related
I want to deny direct access to all files, except one: go.php.
I've read this question, but in my case it doesn't work because I send also a GET parameter.
That means that all files should be denied, except when trying to go to www.domain.com/go.php?code=xyz123.
My code now:
Order Allow,Deny
deny from all
allow from [my IP here]
<FilesMatch "go.php">
Allow from all
</FilesMatch>
How can I fix it?
Thanks!
EDIT 1
I updated the code to:
<Files go.php>
Allow from all
</Files>
Now it does allow if the url is domain.com/go.php?code=123. The thing is that I use pretty URLs with this rewrite condition:
RewriteRule ^go/([a-z0-9]+)$ /go.php?code=$1
RewriteRule ^go/([a-z0-9]+)/$ /go.php?code=$1
So, the above Files code does not work if the url is domain.com/go/123. How to fix this?
Since this is just one specific file, you don't need FilesMatch, but can use Files instead
<Files go.php>
...
</Files>
Rewriting from /go/123 to /go.php?code=123 is a classic. You capture the part for the query string and use it in the substitution
RewriteRule ^go/(.+)$ /go.php?code=$1 [L]
I didn't expect <Files go> or <FilesMatch go> to work, because "/go/123" isn't a file in the strict sense.
So despite my ignorance an additional
<Files go>
Allow from all
</Files>
works.
As an alternative, you can use If and check for the requested URL path
<If "%{REQUEST_URI} =~ m,^/go/,">
Allow from all
</If>
Problem solved:
<FilesMatch "go|go.php">
Allow from all
</FilesMatch>
Thank you all!
I've tried to avoid access files on my webspace in general. Only the index.php should be allowed. I don't want to reach this goal without using mod_rewrite. My actual code is the following:
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
<Files /index.php>
Order Allow,Deny
Allow from all
</Files>
It works when I'm calling my website like www.example.com/index.php, but it doesn't work when I leave the index.php from the URL like www.example.com/
I thought the Apache webserver would know to use the index.php when no segment to the URL is added.
Can you help me out here to understand it and tell .htaccess to allow a raw domain-call?
i think you better have to use some regular expressions to solve this issue
using <FilesMatch> tag instead of <Files> tag
<FilesMatch "^(index\.php)?$">
Order Allow,Deny
Allow from all
</FilesMatch>
I'm triyng to blobk access to certain files.
I have on my server many files like this
filename_sql.php
Basically i need to disallow user to access directly to sql.php files:
http://url.com/filename_sql.php <<<
I have created an htaccess with this code, but i can access files direcly calling url.
What do I wrong?
<Files ~ "\.sql(.php)?$">
Order allow,deny
Deny from all
</Files>
Thanks all.
Your regex expression is matching filenames that end in ".sql.php", but the example filename you listed ends with "_sql.php"
If you remove the first period, it should match requests like "filename_sql.php" (or anything ending with "sql.php"):
<Files ~ "sql(\.php)?$">
Order allow,deny
Deny from all
</Files>
But, an even better method for keeping these files from being directly accessed, would be to move them outside of the root/public directory.
I think this will do the trick
<Files ~ "\.sql(\.php)?$">
Order allow,deny
Deny from all
</Files>
You forgot to put \ before .php.
I have various subfolders on my website and I would like for the user not to be able to access them through URL but on the same time my main PHP files to be able to include them or use them as actions on forms or links.
I tried using an .htaccess with
<Files *>
Order Allow,Deny
Deny from All
</Files>
but it denied all access even from within my own scripts. Logical as I found out, but I cannot know how to make it work. Any ideas?
P.S. My main concern is that some of the files are not included in main PHP files BUT they are linked there and their code ends up with a header('Location: ../index.php'); returning to the main page of the project.
I see a lot of answers with Allow,Deny not Deny,Allow
The order of this matters and is causing the problem. You are telling the computer that deny is more important than allow, because it is listed last. To show you... if you say:
<Files .htaccess>
Order Allow,Deny
Deny From All
Allow From xxx.xxx.xxx.xxx 127.0.0.1
</Files>
You are saying first Allow anyone Allowed, then Deny All... Which still Denies ALL.
If you reverse to Deny,Allow you are saying Deny All, then Allow anyone Allowed.
<Files .htaccess>
Order Deny,Allow
Deny From All
Allow From xxx.xxx.xxx.xxx 127.0.0.1
</Files>
Allow command, being more important, because it is the final command, is therefore allowing those listed after Allow From command.
xxx.xxx.xxx.xxx = Your IP
Do this:
<Files *>
Order Deny,Allow
Allow from 192.168.100.123 127.0.0.1
Deny from all
</Files>
The list of IP's will be specific hosts you allow, like localhost.
This also works with the directive, not just file, if you want only certain directories blocked.
There is an even safer method. Store your include files below the web accessible folders. So if your web files are here...
/var/www/mysite.com/
Store your include files here:
/var/includes/
Then include them with a full path...
include '/var/includes/myincludes.inc.php';
From the web, the myincludes.inc.php file is completely inaccessible.
Usually to protect these logic files from public access you can
put it in protected directory, above htdocs
add a check for public constant.. if(!is_defined(some_root_const)){die();}
change extension to .inc or something.. and deny with .htaccess based on that
put your application code outside of your public html folder. then you can add an include path at the top of your scripts to allow your script to access them as if they were in the same folder.
http://php.net/manual/en/function.set-include-path.php
In you .htaccess you will have to specify which IP's, hosts you want to allow and you can do it per directory as well. for e.g.
<Directory /dir/to/block>
Order Allow,Deny
Allow from 192.168.0.1 4.4.4.4
Deny from All
</Directory>
<Directory /dir/to/allow>
Order Allow, Deny
Allow from All
</Directory>
I'm making a website which allows people to upload files, html pages, etc... Now I'm having a problem. I have a directory structure like this:
-/USERS
-/DEMO1
-/DEMO2
-/DEMO3
-/etc... (every user has his own direcory here)
-index.php
-control_panel.php
-.htaccess
Now I want to disable PHP, but enable Server-side includes in the direcories and subdirectories inside /USERS
Can this be done (and if so, how)?
I use WAMP server
Try to disable the engine option in your .htaccess file:
php_flag engine off
To disable all access to sub dirs (safest) use:
<Directory full-path-to/USERS>
Order Deny,Allow
Deny from All
</Directory>
If you want to block only PHP files from being served directly, then do:
1 - Make sure you know what file extensions the server recognizes as PHP (and dont' allow people to override in htaccess). One of my servers is set to:
# Example of existing recognized extenstions:
AddType application/x-httpd-php .php .phtml .php3
2 - Based on the extensions add a Regular Expression to FilesMatch (or LocationMatch)
<Directory full-path-to/USERS>
<FilesMatch "(?i)\.(php|php3?|phtml)$">
Order Deny,Allow
Deny from All
</FilesMatch>
</Directory>
Or use Location to match php files (I prefer the above files approach)
<LocationMatch "/USERS/.*(?i)\.(php3?|phtml)$">
Order Deny,Allow
Deny from All
</LocationMatch>
If you're using mod_php, you could put (either in a .htaccess in /USERS or in your httpd.conf for the USERS directory)
RemoveHandler .php
or
RemoveType .php
(depending on whether PHP is enabled using AddHandler or AddType)
PHP files run from another directory will be still able to include files in /USERS (assuming that there is no open_basedir restriction), because this does not go through Apache. If a php file is accessed using apache it will be serverd as plain text.
Edit
Lance Rushing's solution of just denying access to the files is probably better
<Directory /your/directorypath/>
php_admin_value engine Off
</Directory>
This will display the source code instead of executing it:
<VirtualHost *>
ServerName sourcecode.testserver.me
DocumentRoot /var/www/example
AddType text/plain php
</VirtualHost>
I used it once to enable other co-worker to have read access to the source code from the local network (just a quick and dirty alternative).
WARNING !:
As Dan pointed it out sometime ago, this method should never be used in production. Please follow the accepted answer as it blocks any attempt to execute or display php files.
If you want users to share php files (and let others to display the source code), there are better ways to do it, like git, wiki, etc.
This method should be avoided! (you have been warned. Left it here for educational purposes)
None of those answers are working for me (either generating a 500 error or doing nothing). That is probably due to the fact that I'm working on a hosted server where I can't have access to Apache configuration.
But this worked for me :
RewriteRule ^.*\.php$ - [F,L]
This line will generate a 403 Forbidden error for any URL that ends with .php and ends up in this subdirectory.
#Oussama lead me to the right direction here, thanks to him.
If you use php-fpm, the php_admin_value will NOT work and gives an Internal Server Error.
Instead use this in your .htaccess. It disables the parser in that folder and all subfolders:
<FilesMatch ".+\.*$">
SetHandler !
</FilesMatch>
This might be overkill - but be careful doing anything which relies on the extension of PHP files being .php - what if someone comes along later and adds handlers for .php4 or even .html so they're handled by PHP. You might be better off serving files out of those directories from a different instance of Apache or something, which only serves static content.
On production I prefer to redirect the requests to .php files under the directories where PHP processing should be disabled to a home page or to 404 page. This won't reveal any source code (why search engines should index uploaded malicious code?) and will look more friendly for visitors and even for evil hackers trying to exploit the stuff.
Also it can be implemented in mostly in any context - vhost or .htaccess.
Something like this:
<DirectoryMatch "^${docroot}/(image|cache|upload)/">
<FilesMatch "\.php$">
# use one of the redirections
#RedirectMatch temp "(.*)" "http://${servername}/404/"
RedirectMatch temp "(.*)" "http://${servername}"
</FilesMatch>
</DirectoryMatch>
Adjust the directives as you need.
I use in Centos 6.10 for multiple folders in virtual host .conf definitioin file:
<DirectoryMatch ^/var/www/mysite/htdocs/(nophpexecutefolder1|nophpexecutefolder2)>
php_admin_value engine Off
</DirectoryMatch>
However, even though it doesn't parse php code the usual way it still outputs from a .php things such as variable declarations and text when doing echo e.g.
<?php
echo "<strong>PHP CODE EXECUTED!!";
$a=1;
$b=2;
echo $a+$b;
The above produces in web browser?
PHP CODE EXECUTED!!"; $a=1; $b=2; echo $a+$b;
This could potentially expose some code to users which isn't ideal.
Therefore, it's probably best to use the above in combination with the following in .htaccess:
<FilesMatch ".*.(php|php3|php4|php5|php6|php7|php8|phps|pl|py|pyc|pyo|jsp|asp|htm|html|shtml|phtml|sh|cgi)$">
Order Deny,Allow
Deny from all
#IPs to allow access to the above extensions in current folder
# Allow from XXX.XXX.XXX.XXX/32 XXX.XXX.XXX.XXX/32
</FilesMatch>
The above will prevent access to any of the above file extensions but will allow other extensions such as images, css etc. to be accessed the usual way. The error when accessing .php:
Forbidden
You don't have permission to access /nophpexecutefolder1/somefile.php on this server.
<Files *.php>
Order deny,Allow
Deny from all
</Files>