Override FilesMatch rule of root htaccess by htaccess from subdirectory [duplicate] - apache

I have an htaccess rule in a folder that disallows php scripts:
<FilesMatch "\.(?i:php)$">
<IfModule !mod_authz_core.c>
Order allow,deny
Deny from all
</IfModule>
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</FilesMatch>
That works just fine. The problem is that there is a specific php script I do want to be able to call (via ajax), so I want to add another rule after the deny that says "but if it is this specific file then allow it". I've done this successfully with other htaccess files in the folder that the file resides with something like this:
<Files ajax_file.php>
<IfModule !mod_authz_core.c>
Order allow,deny
Allow from all
</IfModule>
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</Files>
The problem I am having is that I want to grant a single file access from the same htaccess as the original FilesMatch that blocks all .php files. I can't seem to make it work with adding a file path and am wondering if there is a better way to go about this. The file in question would be a few folders deeper than than the htaccess file that denies the php scripts.

I can see that this is a really old post but, since there is no marked answer I figured I'd try and solve this.
The code you need should look like this:
<FilesMatch "\.(?i:php)$">
<IfModule !mod_authz_core.c>
Order allow,deny
Deny from all
</IfModule>
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</FilesMatch>
That blocks access to all php files and set the priority as allow then deny, so that we can override the deny all later.
Then to allow access to the specific php file use this:
<Files ajax_file.php>
<IfModule !mod_authz_core.c>
Allow from all
</IfModule>
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</Files>
I can see from your OP that this isn't that different to your own, so I can only assume that by re-adding the Order declaration you are causing some weirdness to mess things up, since you already set the priorities in the initial [block all php] files declaration.

I think mod_rewrite is the best and easiest solution to your problem.
RewriteEngine on
# allow access to ajax_file.php
RewriteCond %{THE_REQUEST} ajax_file\.php [NC]
RewriteRule ^ - [NC,L]
#disallow access to other php files
RewriteCond %{THE_REQUEST} .+\.php [NC]
RewriteRule ^ - [F,L]

which linux distribution do you use? there are some htaccess configurators which make it easier to configure these files. you could write something like this
require valid-user
for every file that gets access.

Related

htaccess restrict access to index.php only

I was writing a .htaccess file for my PHP script.
This should only allow access to the index.php, cronjob.php and execute.php pages.
I wrote the .htaccess file as follows:
# Set default index file
DirectoryIndex index.php
# Disable indexing
Options -Indexes
# Set "403 Forbidden" as the default server behavior
Order Deny,Allow
Deny from all
# Allow requests to core PHP files
<FilesMatch "(index|execute|cronjob)\.php$">
Allow from all
</FilesMatch>
# If mod_rewrite module exists...
<IfModule mod_rewrite.c>
RewriteEngine On
# ...restrict access to PHP private directories
RewriteRule (^|/)logs(/|$) - [F]
RewriteRule (^|/)utils(/|$) - [F]
RewriteRule (^|/)modules(/|$) - [F]
</IfModule>
The main problem with this code is that https://example.com/ returns 403 Forbidden,
while https://example.com/index.php works.
You could put condition to check if a URI is NOT having either index.php OR cronjob.php or execute.php then forbid that page so else other pages will be forbid apart from these 3 php uris.
Please make sure you clear your browser cache before checking your URLs.
RewriteEngine ON
RewriteCond %{REQUEST_URI} !(index|cronjob|execute)\.php [NC]
RewriteRule ^ - [F]
In the end I managed to get it to work, I don't know if it's the best .htaccess possible, but this is what I ended up with:
# Set default index file
DirectoryIndex index.php
# Disable indexing
Options -Indexes
# Set "403 Forbidden" as the default server behavior
Order Deny,Allow
Deny from all
# Allow requests to core PHP files
<FilesMatch "^((index|execute|cronjob)\.php)?$"> # Basically, it accepts the three PHP files and the empty string.
Allow from all
</FilesMatch>

Using HTTP Host in filesmatch in htaccess

I am trying to match my sitemap based on host and it doesn't seem to be working. Can you help me figure this out.
My sitemap is sitemap-localhost.xml since i am running on my local
I have tried
<FilesMatch (sitemap-%{HTTP:Host}.xml)>
Order Deny,Allow
Allow from all
</FilesMatch>
<FilesMatch "sitemap-%{HTTP:Host}.xml">
Order Deny,Allow
Allow from all
</FilesMatch>
<FilesMatch sitemap-%{HTTP:Host}.xml>
Order Deny,Allow
Allow from all
</FilesMatch>
But nothing seems to work. The problem is I have two domains pointing to the same folder in the server and the two domains have two sitemaps.
FilesMatch directive is designed to match against files only. You can not check HTTP_HOST header or URL path using this directive, only filename with its extension is allowed in the pattern.
If you want deny access to an xml file of a specific Host ,for example To deny access to thishost.com/sitemap.xml you can use mod-rewrite` .
RewriteEngine on
RewriteCond %{HTTP_HOST} ^thishost\.com$
RewriteRule ^/?sitemap\.xml$ - [R=403,L]
This will return a 403 error to clients if they visit thishost.com/sitemap.xml .
The leading slash ( /? ) in the pattern above is optional so that the Rule can work in both contexts htaccess and server.config .

Troubles with apache - 403 while trying to protect everything but index.php

What I want:
Protecting all files/folders but the index.php.
Apache:
Apache/2.4.2 (Win32) OpenSSL/1.0.1c PHP/5.4.4
Running as Service (xampp 1.8)
Not modified
My project structure
URL: "http://localhost/MyProject/"
PROJECT_DIRECTORY C:/xampp/htdocs/MyProject/
The project directory looks like:
config (folder)
ressources (folder)
sources (folder)
index.php
Problem:
I am having troubles with my .htaccess file as I do always receive a 403 or even a 500 Error.
I tried different settings to achieve the goal but none of these worked. I tried Directory, DirectoryMatch, Files, FilesMatch etc.
But I think it should be as easy as:
# Activate rewrite engine
RewriteEngine on
RewriteBase /
# Redirect all requests to index.php
RewriteRule ^(.*)$ index\.php?/$1 [QSA]
# Deny from all
Order deny,allow
Deny from all
# Allow only index.php
<Files "index.php">
Allow from all
</Files>
Or something like this:
...
# Deny from all
<Directory />
Order deny,allow
Deny from all
</Directory>
# Allow only root dir
<Directory "/MyProject" />
Allow from all
</Directory>
May someone can help me with this?
EDIT: I recently found out, that I cannot use the tag as the .htaccess is valid for the directory I put it in, so there is no need to define that directory inside .htaccess. This did not solve my problem but I know that the second example is wrong.
You can try this:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(index\.php)$
RewriteRule ^ - [L,F]
This will let requests for / and /index.php pass through while responding with a 403 Forbidden for anything else.
However, you've got this rule already:
# Redirect all requests to index.php
RewriteRule ^(.*)$ index\.php?/$1 [QSA]
So you don't really need to deny anything if everything is already being routed through index.php

htaccess: Conditional Authentication

How can i configure this in my apache/htaccess configuration:
I want HTTP-Authentication for all files with one exception.
The files click.php and js/clickheat.js may be accessed from 1.2.3.4 without any authentication.
I tried FilesMatch, but i can't invert it. So i can't put require valid-user in there. I thought using SetEnv, but how do i check for it later?
<FilesMatch "(click\.php|clickheat\.js)">
# what here?
</FilesMatch>
My other idea was to use mod_rewrite. Well, i can allow access to the two files from the given host and deny it from anywhere else. But how do i chain it with HTTP-Authentication?
# allows access to two files from the given IP
RewriteCond %{REMOTE_ADDR} 1\.2\.3\.4
RewriteCond %{REQUEST_URI} ^/click.php [OR]
RewriteCond %{REQUEST_URI} ^/js/clickheat\.js
RewriteRule (.*) - [L]
# denies everything else
RewriteRule (.*) - [F,L]
So my favourite solution would be enabling HTTP-Auth via RewriteCond/RewriteRule.
Background (or why i want to do this): I'm trying to secure a clickheat (http://www.labsmedia.com/clickheat/index.html) installation. And 1.2.3.4 is the remote running mod_proxy and redirecting access to these to files to our clickheat host.
Ok, i found a solution:
Order Deny,Allow
Deny from All
Satisfy Any
AuthType Basic
AuthName "clickheat"
AuthUserFile /var/www/clickheat/.htpasswd
Require valid-user
<FilesMatch "(click\.php|clickheat\.js)">
Deny from All
Allow from 1.2.3.4
</FilesMatch>
The key is the Satisfy Any which allows either IP- or Auth-based access.

mod_rewrite rules and content negotiation

I am relatively new to mod_rewrite, but have a site which I would like to have "pretty urls." Similarly to SO :).
I am attempting to have things like: "http://www.whatever.com/search/test" get rewritten to "http://www.whatever.com/search.php?q=test" and have had some limited success. I believe that content negotiation is getting in my way...
For starters here's my test .htaccess file:
RewriteEngine on
RewriteBase /~user/mysite/
RewriteRule ^search$ search/ [R]
RewriteRule ^search/([^/]*)/?$ search.php?q=$1 [L]
Which unfortunately, does redirect to search.php, but does not pass my param in the q variable. However this does work:
RewriteEngine on
RewriteBase /~user/mysite/
RewriteRule ^search$ search/ [R]
RewriteRule ^search/([^/]*)/?$ s.php?q=$1 [L] # here i've renamed the search.php to s.php to dodge the content negotiation that is happening..
In fact, if I remove the rules all together, I get the same result as with the first version of the file. So my conclusion is that since apache is happily redirecting "foo" to "foo.php" even without any mod_rewrite rules, that it must be the content negotiation that is taking care of it. (This is further verified by the fact if I renamed my foo.php to foo.html, it still will find the file if i just go to "foo").
So, the question is. How do I properly use mod_rewrite with regard to content negotiation? Can I disable it for a particular file? Is there a way to ensure that my mod_rewrite rules happen before the content negotiation happens?
If it is relevant, here is the conf file for the mod_userdir part of my apache conf (this test site is in my user's homedir/public_html):
# Settings for user home directories
<IfDefine USERDIR>
<IfModule userdir_module>
# UserDir: The name of the directory that is appended onto a user's home
# directory if a ~user request is received. Note that you must also set
# the default access control for these directories, as in the example below.
UserDir public_html
# Control access to UserDir directories. The following is an example
# for a site where these directories are restricted to read-only.
<Directory /home/*/public_html>
AllowOverride FileInfo AuthConfig Limit Indexes
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
<Limit GET POST OPTIONS>
Order allow,deny
Allow from all
</Limit>
<LimitExcept GET POST OPTIONS>
Order deny,allow
Deny from all
</LimitExcept>
</Directory>
# Suexec isn't really required to run cgi-scripts, but it's a really good
# idea if you have multiple users serving websites...
<IfDefine SUEXEC>
<IfModule suexec_module>
<Directory /home/*/public_html/cgi-bin>
Options ExecCGI
SetHandler cgi-script
</Directory>
</IfModule>
</IfDefine>
</IfModule>
</IfDefine>
Look for this option in your configuration.
Options +Multiviews
It will look for
/foo/test
/foo/
/foo
and redirect them to
/foo.[any file]
based upon if it exists and if it fits the content-type requested.
Change the option to this to disable this.
Options -Multiviews