Apache : Restrict access to URI, not resource - apache

I'd like to restrict access to some URIs, but they do not physically match a clearly identified resource.
I explain : if you ask http://domainname/admin, you do not strictly go to the admin dir, you go to a script, with some params; and this script can also be used in other contexts.
So, i'd like to make something like folder access restriction, but based on the URI asked for, not on the actuel resource (cause the /admin folder exists, of course :D).
How could i do that ?
TIA

In .htaccess Add the rewrite rule:
RewriteRule ^admin - [F,L]
This will deny access to paths starting with admin.

Use <Location>/</Location> tags in your httpd.conf (or whatever it's called this week), insert any access restrictions between the tags. For instance
<Location /admin>
Order deny,allow
Deny from all
Allow from localhost, admins-workstation.example.com
</Location>

Related

Block access to PHP file using .htaccess

I want to block direct access to PHP file, for example when someone enters it manually in the address bar (https://example.com/php/submit.php). I used this code:
<Files "submit.php">
Order Allow,Deny
Deny from all
</Files>
But if I block it this way, the form can't be submitted (it doesn't send mails).
Is there another way to block direct access but to be able to submit form?
<form id="form" action="php/submit.php" method="post">
Your form is making a POST request, whereas "when someone enters it manually in the address bar" they are making a GET request. So, you could block anything but POST requests..
Using <LimitExcept>
For example, surround your existing directives in a <LimitExcept> container:
<LimitExcept POST>
<Files "submit.php">
Require all denied
</Files>
</LimitExcept>
Note that this blocks non-POST requests to any submit.php file on your system.
NB: Order, Allow and Deny are Apache 2.2 directives and formerly deprecated on Apache 2.4 (which you are more likely to be using, unless you are on LiteSpeed). Require all denied is the Apache 2.4 equivalent. However, you should not mix authentication directives from both modules.
Using mod_rewrite
Alternatively, using mod_rewrite near the top of the root .htaccess file you can target the /php/submit.php URL-path directly. For example:
RewriteEngine On
RewriteCond %{REQUEST_METHOD} !=POST [NC]
RewriteRule ^php/submit\.php$ - [F]
The above will serve a 403 Forbidden for any request to /php/submit.php that is not a POST request (eg. when a user types the URL directly in the browser's address bar).
Alternatively, check that the request is a GET request. ie. =GET
HOWEVER, you should already be performing this check as part of your standard form validation in your PHP code, so this additional check in .htaccess should be redundant. (After all, how are you checking that the form has been (successfully) submitted?)

Rewrite directory path based on authentication data

I'm trying to provide my users a unique directory under one common URL (https://example.com/sync). Previously I managed this with a rewrite rule which just appended the remote users name to the root directory for "sync". Now, the users login ID differs from the directory name. As per apache documentation, authn_dbd provides additionally returned columns in extra variables with the prefix AUTHENTICATE_.
<Directory "/srv/www/sync/">
AuthDBDUserPWQuery "SELECT passphrase, identifier FROM webserver.fn_authenticate_context('SYNC') where login_id = %s"
RewriteEngine On
RewriteCond %{AUTHENTICATE_IDENTIFIER} ^(.+)$
RewriteRule ^\/(.*)$ /%{AUTHENTICATE_IDENTIFIER}/$1 [NS,L]
</Directory>
This should provide the required identifier for my rewrite rule. However, the identifier seems not to be available when rewriting occurs. Adding a header with the content to the response works and provides the content.
Activating logs up to trace8 shows that authentication is processed first and afterwards the rewrite conditions are processed but the value is still empty.
After searching around for quite a while, I found no reliable way to use the different "features" of Apache dbd. It produces variables for additionally returned columns - or not. The variables are available in CGI but not before or even not there. Errors are only logged during startup phase and later silently discarded. So if you don't get successful authentication at all, the root cause may be a permission problem. The only way to verify this is by executing the request with the credentials that dbd uses for access to the database.
The solution to my original issue is to forget about the documented option of additional columns from the authentication request and running an additional, separate request to the database. The working snippet:
### Cloud Synchronization (Web DAV service)
Define _SYNC_CLOUD_PREFIX /sync
# We need the rewrite engine here...
RewriteEngine On
# define a rewrite map which looks up the home directory for the user...
RewriteMap dbd_sync_home "dbd:SELECT dir_home FROM webserver.authorize_for_context('SYNC', %s);"
# redirect /sync to /sync/
RedirectMatch permanent ^${_SYNC_CLOUD_PREFIX}$ ${_SYNC_CLOUD_PREFIX}/
# Rewrite /sync/xxx to /srv/www/sync/<domain>/<user>/xxx
RewriteCond %{LA-U:REMOTE_USER} ^(.+)$
RewriteCond %{REQUEST_URI} ^${_SYNC_CLOUD_PREFIX}
RewriteRule ^${_SYNC_CLOUD_PREFIX}/(.*)$ /srv/www/sync/${dbd_sync_home:%{LA-U:REMOTE_USER}}/$1 [L]
# Authorize when hitting the location /sync/
<Location "${_SYNC_CLOUD_PREFIX}/">
DAV On
SSLRequireSSL
Options +FollowSymLinks
AuthType Basic
AuthName "Sync Heaven"
# To cache credentials, put socache ahead of dbd here
AuthBasicProvider socache dbd
AuthnCacheContext www-sync
AuthnCacheProvideFor dbd
# mod_authn_dbd SQL query to authenticate a user
AuthDBDUserPWQuery "SELECT passphrase FROM webserver.authorize_for_context('SYNC', %s);"
Require method OPTIONS
Require valid-user
</Location>
UnDefine _SYNC_CLOUD_PREFIX

How can I restrict access to a folder or a file to other users in htaccess?

I want to restrict access to some folders and files but only when a user tries to access to it through the url, not when the website access to these files. For example restrict the folders images, javascript,...
I tried in different ways but I always got error 500.
Basically, I don't want external users to list my website directory and open their files, if it is possible to accomplish.
Thanks in advance
This is pure mod_rewrite based solution:
RewriteRule ^(includes/|submit\.php) - [F,L,NC]
This will show forbidden error to use if URI contains certain paths.
You are getting a 500 error because the container cannot be used in an htaccess file (which is essentially all inside a directory container for the directory that it's in). What you need to do is remove the container from your htaccess file, and leave the Deny from all bit:
htaccess file in your document root:
Refuse direct access to all files
Order deny,allow
Deny from all
Allow from 127.0.0.1
Then create an htaccess file in the uploads/files/, uploads/images/pages/ and uploads/images/store/ (and whatever other directories that you want to allow access to):
Allow from all
put .htaccess and edit with "Deny from all".
That's it.

Removing .htaccess Authentication Restrictions

I have a project that has .htaccess Authentication but i want to remove it for a certain assets folder.
i tried adding a htaccess in that folder with :
AuthType none
Satisfy Any
Allow from All
Order Allow, Deny
but it doesnt seem to work :(
Any thought on this. Thank you so much
Edit
The directory i am trying to unprotect is not a real directory, but a rewrite rule.
I dont have access to httpd.conf
Without seeing your full .htaccess I'm guessing, but what about something like this:
RewriteEngine On
RewriteRule ^assets/ - [E=allow-assets:1]
Allow from env=allow-assets
That could go in the .htaccess of the parent directory, not assets.
You could possibly do this if you have access to /etc/httpd.conf -- do you?

How can I block mp3 crawlers from my website under Apache?

Is there some way to block access from a referrer using a .htaccess file or similar? My bandwidth is being eaten up by people referred from http://www.dizzler.com which is a flash based site that allows you to browse a library of crawled publicly available mp3s.
Edit: Dizzler was still getting in (probably wasn't indicating referrer in all cases) so instead I moved all my mp3s to a new folder, disabled directory browsing, and created a robots.txt file to (hopefully) keep it from being indexed again. Accepted answer changed to reflect futility of my previous attempt :P
That's like saying you want to stop spam-bots from harvesting emails on your publicly visible page - it's very tough to tell the difference between users and bots without forcing your viewers to log in to confirm their identity.
You could use robots.txt to disallow the spiders that actually follow those rules, but that's on their side, not your server's. There's a page that explains how to catch the ones that break the rules and explicitly ban them : Using Apache to stop bad robots [evolt.org]
If you want an easy way to stop dizzler in particular using the .htaccess, you should be able to pop it open and add:
<Directory /directoryName/subDirectory>
Order Allow,Deny
Allow from all
Deny from 66.232.150.219
</Directory>
From this site: (put this in your .htaccess file)
RewriteEngine on
RewriteCond %{HTTP_REFERER} ^http://((www\.)?dizzler\.com [NC]
RewriteRule .* - [F]
You could use something like
SetEnvIfNoCase Referer dizzler.com spammer=yes
Order allow,deny
allow from all
deny from env=spammer
Source: http://codex.wordpress.org/Combating_Comment_Spam/Denying_Access
It's not a very elegant solution, but you could block the site's crawler bot, then rename your mp3 files to break the links already on the site.