htaccess rules to block all but server - .htaccess

looking for some htaccess rewrite rules to block all access to a directory except for the server itself. It's a directory full of images and flash swf files. Yes I know it's sort of odd to not want direct access to a file its own directory, but to allow it to be seen by the user when referenced in other html outside the protected directory, but thats what i'm after. I have tried a few different methods as shown below:
# send them to index.php
Options +FollowSymlinks
RewriteEngine on
#RewriteRule ^(.*)$ ../User/ [NC]
#RewriteRule ^(.*)$ [R=301,L,NC]
# no one gets in here!
#deny from all
Options All -Indexes
<Limit GET POST PUT>
order deny,allow
deny from all
allow from 192.168.0.0/33
</Limit>
None of them seem to really do what I want. some of them block access to everything, including the server itself. Other redirect the request to another page, but because it keeps the same url, the links on the 'page' the user gets redirected to wont work.
If possible I would not even like to do a 404 warning, because while this disallows users access to the directory, the user will still know that that directory exists.

You can simply use this one line rule to do that:
RewriteRule ^mydir/ - [L,R=404,NC]
That way all the files under /mydir/ will generate 404 errors to your visitors but your server will still have access to those files.

Related

Can htaccess prevent all access to unwanted files?

I'm building something that I want to release as an open source project. To make it easier to use I'd like to go without the public-folder approach, where you hide all other files than index.php (and assets) from public_html. Meaning, I'd like to do it like WordPress, where you simply toss the code on a server and it works, in that URL you tossed it in.
Here is the content of my htaccess-file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
</IfModule>
Does this code really prevent access to other files? For example, is there any way an attacker could access vendor/Acme/Libraries/Foo.php? Based on my tests it does, but that doesn't mean there isn't a way to circumvent it.
Let's look at your rule closely:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
Here this rule is saying that if request is NOT for a valid file then rewrite it to /index.php. Which means /index.php will be invoked for any non-file requests but that also means you are allowing direct access to all the files.
btw QSA is useless here and can be removed.
You cited Wordpress here. Which basically uses /index.php for any non-file, non-directory requests thus allowing direct access to any valid file OR directory.
If you really want to block access to all the files and directories then you probably will need this rule:
RewriteRule ^ index.php [L]
but I am not sure if you want to handle direct access to resources like images, js/css files via index.php also.
Yes, an attacker can still access your other code files, using only the rule you provided. But:
On a properly configured server, a call to vendor/Acme/Libraries/Foo.php would execute that file, not display its contents. Which might or might not be good enough, and there's still the possibility of a configuration error that would display the source code.
You can block web access to the remaining files by adding Deny directives, for example:
<Location />
Order deny,allow
Deny from all
<Files index.php>
Allow from all
</Files>
</Location>

htaccess rule - Take the Place of Symlinked Files

I'm working on this legacy project that has a rather odd setup that I'm looking to get rid of but my htaccess skills are a little lacking in this department.
Here's the directory structure.
/index.php
/www
page1.php -> symlink to index.php
page2.php -> symlink to index.php
page3.php -> symlink to index.php
/www is the public directory and people visit http://site/page1.php. However, each of those files with an * actually symlinks to /index.php.
I find this arrangement idiotic and would like to get rid of the symlinks and simply have any /www/*.php request simply point at index.php without the page actually redirecting to index.php.
Any ideas for an htaccess rule(s) that could solve this problem? At its most basic core, I'd like to keep the same functionality without having to have a thousand symlinked files.
It looks like the index.php file is not in your document root (which I'm assuming is www), and because of that, I don't think there's a way you can do this from your .htaccess file. In order to access something outside of your document root, you'll need to setup an alias in either your server config or your vhost config:
# Somewhere in vhost/server config
Alias /index.php /var/www/path/to/index.php
# We need to make sure this path is allowed to be served by apache, otherwise
# you will always get "403 Forbidden" if you try to access "/index.php"
<Directory "/var/www/path/to">
Options None
Order allow,deny
Allow from all
</Directory>
Now you should be able to access /var/www/path/to/index.php. Note that other files in the /var/www/path/to directory is safe as long as you don't create an Alias (or AliasMatch or ScriptAlias) that points to them. Now that you can access index.php via the /index.php URI, you can setup some mod_rewrite rules in the .htaccess file in your document root (www) to point things to index.php:
# Turn on the rewrite engine
RewriteEngine On
# Only apply the rule to URI's that don't map to an existing file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all requests ending with ".php" to "/index.php"
RewriteRule ^(.*)\.php$ /index.php [L]
This will make it so when you request http://site/page1.php, the browser's address bar is unchanged but the server actually serves /index.php, which is aliased to /var/www/path/to/index.php.
You can tweak the regular expression ^(.*)\.php$ to something more appropriate if need be. This just matches anything that ends with a .php, including /blah/bleh/foo/bar/somethingsomething.php. If you want to limit the directory depth, you can tweak the regular expression to ^([^/]+)\.php$, etc.

Use htaccess to only allow download of files if user agent is a specific type

I have a folder with some zip files in it. I want to reject all requests to download them directly unless the user agent is of the type I specify (eg. user-agent : myuseragent)
How is this possible with .htaccess file?
Rejected requests would redirect to the index file while accepted requests will download the file.
eg. if a user tried http://download.com/files/myfile.zip they would get rejected but if a script with a useragent of 'myuseragent' access the same url, it would download the file
I understand that useragents can be spoofed. It is only mild protection from having the files freely available
Here how you can do it using .htaccess and mod_rewrite:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} !=myuseragent
RewriteRule ^files/.*$ - [F,L]
The above rule will instruct Apache to issue 403 Access Denied response for any file in /files/ folder if user agent is not equal to myuseragent.
If you want to issue 404 File Not Found response, replace [F,L] by [R=404,L].
If you want to redirect such failed requests to home page then use this rule (you can change redirect from 302 to whatever other redirect code you like):
RewriteCond %{HTTP_USER_AGENT} !=myuseragent
RewriteRule ^files/.*$ / [R=302,L]

How can I redirect to another file but keep index.php access

I will try to explain this in the simplest terms I can think to avoid confusing anyone.
I have a site that I've moved to a subdirectory, it will go away soon but for needs access. In the root I have a wordpress install with an index.php file.
Basically for the time being I need this:
User types www.site.com they get taken to www.site.com/comingsoon.php
User types www.site.com/index.php they get taken to that actual URL (no redirect)
This is the only line I have in my .HTACCESS:
DirectoryIndex comingsoon.php
but that doesn't seem to work as if they go www.site.com/index.php (by typing that explicitly) they still get redirected to the coming soon page.
I can't rename the index.php from wordpress.
Any help is appreciated.
Try this code in your .htaccess file:
Options +FollowSymlinks -MultiViews
RewriteEngine on
RewriteRule ^/?$ /comingsoon.php [L]
This will only internally redirect www.site.com or www.site.com/ to /comingsoon.php. But if you type www.site.com/index.php it should not do any redirection.

.htaccess allow script access within my domain

I am looking for the specific .htaccess command that will allow me to deny http access from everyone BUT my scripts.
I have a script that runs out of the root directory that goes and fetches all of the .jpg's out of a given protected directory with the following .htaccess file
<files *.jpg>
order allow, deny
deny from all
</files>
I was thinking something similar to this might work
<files *.jpg>
order allow, deny
deny from all
allow from rootUrl.com
</files>
Your first example should work, since scripts don't make any HTTP requests.
Edit: Unless, your script for some strange reason makes HTTP requests to its own server, which I really don't think it does. Nor should it.
Edit again: Since your script is outputting img elements pointing to the protected files, you have to let all visitors access the files. There is no work-around. You could however stop hotlinking by using .htaccess like this:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?yoursite\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule .*\.(jpe?g|gif|bmp|png)$ [F]

Resources