.htaccess <Files> locking me out of subdirectories - php

I have the following in a .htaccess file on my server:
<Files index.php>
Order Deny,Allow
Deny from All
Allow from 80.168.22.149
</Files>
The .htaccess is located in a subdirectory, at www.example.com/subdir/.htaccess
The index.php file is located in the same subdirectory.
It gives the usual error if I try and access the page from another IP:
Forbidden
You do not have permission to access this document.
However, when I try and access a subdirectory such as /subdir/images, I get the same error. This error appears if I try and access from an allowed OR disallowed IP address. I thought that the <Files> limitation would only disallow access to the specified files?
I need to be the only IP address that can access index.php, but I need to be able to link to subdirectories within /subdir/ and let anyone view them.

Rather than <Files> directive you can use this rewrite rule in /subdir/.htaccess:
RewriteEngine On
RewriteBase /subdir/
RewriteCond %{REMOTE_HOST} !=80.168.22.149
RewriteRule ^index\.php$ - [F,NC]

The problem with your <Files> directive is that it is matching every index.php including the index.php files in the sub directories.
The only way around this is to use a <Location> directive instead, but you're not able to use that in a .htaccess file.
You would need to edit the Apache configuration file instead and add the <Location> directive in there inside the <VirtualHost> directive for the domain

Related

.htaccess - Deny access to folder but allow access to file via index.php

I'm having a problem with .htaccess and PHP-files in a sub folder. What I'm trying to achieve is to prevent anyone from being able to access any file in my sub folder - BUT I want my index.php to be able to access those files.
DOCROOT/subfolder -> www.somewebsite.com/subfolder/somefile.php
-> Access Denied
BUT
[index.php]
<form action="/subfolder/somefile.php">
...
</form>
-> Success!
I would love to solve this by just using .htaccess. I tried deny from alland also some RewriteRules but those Rules also kill any request from index.php.
I tried
Order deny,allow
Deny from all
Allow from 127.0.0.1
Allow from somewebsite.com
Satisfy Any
but the request from index.php is being denied. Can anyone help, please?
This is a misconception that people have. Just because you're linking to PHP files from another PHP file doesn't mean the index.php file is accessing them. The end-user/browser is still accessing them, it's just it's being told where to go by your index.php file. Has absolutely nothing to do with how it's being accessed. In both of your cases, they're being accessed by the browser.
The best you can do is to look at the referer field. It can be easily forged to get around this, but it's the only thing you can do.
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^https?://(example.com|127\.0\.0\.1) [NC]
RewriteRule ^subfolder/ - [L,F]
where "example.com" is your site.
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://www.hello.com/index.php
RewriteRule .*subfolder/somefile\.php - [NC,F]
The second line checks whether the visitor is not coming from a certain url. The 3rd line blocks them from accessing somefile.php
In your .htaccess you could redirect any requests to files inside that directory other than index.php as follows:
<directory "DOCROOT/subfolder">
RewriteCond %{REQUEST_FILENAME} !=/DOCROOT/subfolder/index.php
RewriteRule ^/(.+)$ redirect.php [L]
</directory>

PHP Directory rewrite rules

I've the following structure for my MVC php application.
/
/Models/
/Views/
/Content/
/libs/
index.php <-- Controllers
admin.php
blog.php
Basically I want people to allow acces .php files in the root directory. (index.php, admin.php)
For example allow only acces to index.php
<Files *.php>
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
</Files>
<Files index.php>
Order Allow,Deny
Allow from all
</Files>
For some strange reason people can acces URL's like index.php/index.php/index.php
or blog.php/test/ it will display the output page but it doesn't render properly.
Why is this happaning?
For some strange reason people can acces URL's like index.php/index.php/index.php
It's not a BUG, it's a FEATURE ;)
This is actually an apache feature. Apache allow addtional path information after the script name. In php you can acesss this value from $_SERVER['PATH_INFO']
The URL index.php/a/b will run the script index.php and you will get "a/b" in PATH_INFO
How to disable this type of URL
To disable such url you need to disable "AcceptPathInfo" in apache configuration
<Files "*.php">
AcceptPathInfo Off
</Files>
You can find more about AcceptPathInfo in http://httpd.apache.org/docs/2.2/mod/core.html#acceptpathinfo
Basically I want people to allow acces .php files in the root directory. (index.php, admin.php)
Instead of <Files> directive use mod_rewrite for finer control:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(index|admin)\.php$ [NC]
RewriteCond %{THE_REQUEST} \.php[\s?/] [NC]
RewriteRule ^ - [F,NC]
/index.php/index.php/index.php isn't a valid path. The root /index.php is still the one that is being run by the server. However the browser isn't smart enough to know this so if you paths to css and image files are relative it is now looking for them in the wrong places that is why your page isn't rendering properly.
So as far as the server is concerned www.test.com/index.php/index.php/index.php is the same as calling www.test.com/index.php
But for the browser if you had this in your html header <link href="css/style.css" rel="stylesheet" type="text/css"> it is now trying to find it in www.test.com/index.php/index.php/css/style.css and of course it doesn't exist there.

Allow .htaccess only from one directory to another

I have mp3's in a directory called /mp3/ and I want to be able to access them only from another page.php in another directory /main/ on the site.
No direct linking from outside.
All of the pages are written in php
I put this code in the .htaccess file inside the /mp3/ directory...
Order deny,allow
deny from all
allow from 127.0.0.1
allow from localhost
allow from mydomain.com
allow from 123.45.678.90 # that's myserver's IP address (real one used in code)
Satisfy Any
But none of those work.
It does work however if I use the IP address of were I am.
allow from 1.2.3.4 # my internet connection (real one used in code)
But that means it would work for anyone and their IP address.
What am I missing here? Does this work only on certain servers?
How do I make it use the server's IP address and not my IP address?
Look into "hotlink protection" added to your .htaccess file. You can set it up for just .mp3 file extension, and forbid access by any foreign site or directly from browsers. You might even be able to restrict access from within your own site, but I can't see that being terribly useful.
Something like
RewriteEngine on
Options +FollowSymlinks
# hotlink protection and allowed list
# don't forget to add https: to allow accesss for any with SSL
## uncomment following line to PERMIT direct browser access of mp3 files
#RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?yourdomain\.com(/)?.*$ [NC]
RewriteRule .*\.mp3$ - [F,NC]
Place the files you want to protect out of the public folder. This way they are only accessible via your scripts.
-root
--mp3s
--public_html
---main
----index.php
----page.php
You are trying to limit a "referral" and not direct access?
Denying from an IP limits all access, whether referred to by your page.php or by typing it into the browser's URL location bar. If you're trying to limit referrals, you can try using something like:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?yourdomain.com/ [NC]
RewriteRule ^mp3/ - [L,F]
but be warned that referers can be spoofed.
What about something like this, in your .htaccess
<Files ~ ".mp3$">
Order allow,deny
Deny from all
</Files>
This will not allow direct access to any files with .mp3 from your web server.
Place this code in your mp3/.htaccess file:
RewriteEngine on
RewriteBase /mp3/
RewriteCond %{HTTP_REFERER} !^https?://(localhost|(www\.)?mydomain\.com)/ [NC]
RewriteRule ^ - [F]

Use .htaccess to set 404 error document located in the same folder

So... i am trying to set the path to an error document located in the same directory as the .htaccess (located in the WEBSITE "root") like this:
ErrorDocument 404 404.php
However instead of showing the webpage...it just writes 404.php on the screen. I can't use absolute paths like:
ErrorDocument 404 /404.php
Because i am not doing the website for me and i do not know the absolute path of the folder the website will be stored on...
My question is: Can i set relative paths in the .htaccess document rather than absolute ones? (and if yes...how?)
The URL-path in the argument of the ErrorDocument directive is always relative to the DocumentRoot.
However, you can work around this using the mod_rewrite module.
RewriteEngine on
#if requested resource isn't a file
# and isn't a directory
# then serve local error script
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* 404.php [L]
Make sure the 404.php does actually emit a 404 response header!
I haven't tested it, but this should get you started. Also note that using the ErrorDocument directive is always preferable to this, and asking where the site will reside relative to DocumentRoot would be sensible, so you'd be able to write
ErrorDocument 404 /path/to/my/site/404.php
While a number of directives are sensitive to relative directory while within an .htaccess or <Directory> context, ErrorDocument is not. Per the documentation:
URLs can begin with a slash (/) for local web-paths (relative to the
DocumentRoot), or be a full URL which the client can resolve.
Source
ErrorDocument paths are relative to the DocumentRoot server setting, which is usually found in /etc/apache2/sites-enabled/000-default.conf This is how it looks in my file:
<VirtualHost *:80> <---------------- VirtualHost on port 80 is generally internet traffic
ServerAdmin webmaster#localhost
DocumentRoot /var/www/ <-------- this is what we're looking at
</VirtualHost>
Note that the DocumentRoot set in this file is absolute in the filesystem - var is in the bottom level folder /.
So my .htaccess file resides in /var/www/myapp/.htaccess, meaning that the .htaccess file exists one directory down from DocumentRoot (which is set to /var/www/). So in order to have my ErrorDocument 404 served from /var/www/myapp/errordocs/404.html, I need to set, in my .htaccess, the following:
ErrorDocument 404 /myapp/customErrorPages/custom_404.html
Note that even though the .htaccess file resides in the myapp folder, I still need to include the /myapp/ in the path, as the path is relative to the DocumentRoot as defined in /etc/apache2/sites-enabled/000-default.conf
Also note that the path must start with a / in order for apache to read it as a path. Setting "myapp/customErrorPages/custom_404.html" (without the leading /) will result in just that string being printed instead of a document being served.
Pretty confusing if you don't have knowledge of directory paths in linux and configuration files in apache, but keep poking around you'll get it ;)

how to prevent users having access to a particular directory

I have a directory named "includes" containing information about my database and some other important files that users should not access. I want to use an .htaccess file to redirect requests that begin with "/includes" to errors/403.html. This is my code but it does not work. What's the problem?!
RewriteEngine On # Turn on the rewriting engine
RewriteRule ^/includes/([a-zA-Z]+)/?$ /errors/403.html [NC,L]
If your config files are php, you can just place empty index.php in that directory or create .htaccess with Options -Indexes or Deny from All there (in includes/).

Categories