Deny access to a folder from direct url - php

So I've found many posts here on how to do a similar action, however, I'm still confused. So here is my question. I want to have access to www.mywebsite/folder/index.html but if I were to remove the index.html and just type in www.mywebsite/folder/ I don't want to have access to that. How can I go about doing this? I read that I can use an .htaccess file with deny from all but that restricts me from the whole folder and I can't access the index.html.
Please let me know if there is a solution or another post that I missed that outlines the exact situation.
Thank you!

Which Apache version are you using? In 2.4, you can use DirectoryIndex disabled to stop it from automatically serving up the index.html, and combine that with Options -Indexes.
In lower versions disabled does not exist yet, so using mod_rewrite with a simple RewriteRule that forbids access when the exact folder path (with or without trailing slash) was requested should do it,
RewriteRule ^folder/?$ - [F,L]
To control what error message the user gets to see in each case, specify the ErrorDocument for the 403 Forbidden status code.

Related

deny access php page but still make it possible to be included

I am currently running a PHP website, and I was wondering if there is any way to deny access to an image, if the directory was entered in the browser bar, but still be able to use said image in my Page with the <img src=""> tag.
I store said image in a directory called "images" which is on the same level with my main page "home.php". I am familiar with the .htaccess file and the deny from all command in it, however, as I said, it will not display the 'forbidden' files in the other pages. I hope that somebody can help me. Thanks!
Maybe you can try this:
<Files "./your_directory/yourfile.png">
Order Allow,Deny
Deny from all
</Files>
Basically, I believe that the answer would be "no," because in both cases the user's browser is the party making the request. Apache might not know or be able to distinguish between two "reasons" why the browser is making such a request.
On the other hand, programmatic code within your host-side application possibly could. Either directly or using mod_rewrite tricks, you could direct the incoming request to a server-side script, which can examine the entirety of the HTTP request and determine what sort of response it should produce: image-content, or 404. In this scenario, Apache accepts the request ... does not Deny it ... but instead of serving the image directly itself, it hands-off to a script which makes that decision. (The script can still gulp the data from a file, probably from a directory that Apache will not directly serve at all, so it can be "reasonably fast.")
By the way: you can use directives, at the <Directory> or <Location> level, to force "hand this request off to such-and-such script" behavior, so that, when the user's browser "requests such-and-such image," Apache runs that handler-script instead, passing a URL that includes the name of the requested file. The user won't be able to know what actually happened.)
You can accomplish this many ways, but internet jargon this is called "hotlinking". You can use this tool http://www.htaccesstools.com/hotlink-protection/ to create your own .htaccess file.
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]

Accessing a file through .htaccess

i'm new to stack overflow, and to .htaccess too, so let's come to the point.
I have a file lessons(.php) in my root directory and i want it to appear like it doesn't exists there through .htaccess
So i'm using these directives to achieve one of my goal:
<Files lessons.php>
Order Deny,Allow
Deny from All
</Files>
I only know that i'm denying access to that file in my directory, nothing more
And my second question is that i want this file to be able to access only for certain conditions, means when someone try to access that link
RewriteRule ^library/lessons/([a-z-]+) lessons?lesson=$1 [NC,L]
In other words
library/lessons/ba-blah-blah-whatever/
So how i can do this, accessing file just like an if/else condition, means if someone is on that link mentioned up there can access that file, i know that i can't use if/else in .htaccess but you know what i want to say
I'm pretty sure you don't need anything so complicate. Just write a proper route with mod_rewrite:
RewriteRule ^library/lessons/([a-z-]+) lessons.php?lesson=$1 [NC,L]
... and if you really really can't allow access through the actual file name, prevent access right from PHP filtering $_SERVER['REQUEST_URI'] and aborting with 404 status code.

301 redirect in .htaccess for 30,000 errors

I've been tasked to clean up 30,000 or so url errors left behind from an old website as the result of a redesign and development.
I normally use .htaccess to do this, but I doubt it would be wise to have 30,000 301 redirects inside the .htaccess file!
What methods have some of you used to solve this problem?
Thanks in advance.
Here as you can do with apache httpd
RewriteMap escape int:escape
RewriteMap lowercase int:tolower
RewriteMap my_redir_map txt:map_rewrite.txt
RewriteCond ${my_redir_map:${lowercase:${escape:%{HTTP_HOST}%{REQUEST_URI}}}} ^(.+)$
RewriteRule .* http://%1 [R=301,L]
I use this rewrite rules usually directly inside apache httpd configuration.
Inside the map_rewrite.txt file you have a tab delimited file with the list of redirect in the following format:
www.example.it/tag/nozze www.example.it/categoria/matrimonio
www.example.it/tag/pippo www.example.it/pluto
www.example.it/tag/ancora www.google.com
Would be much easier if you can generalize the approach because the redirect have a common pattern. But if not, in this case you only need to add the redirected url into the list.
Take care to study the RewriteMap configuration, because you can also write the list into a different format, for example like a database table.
Please pay attention to this: I have added escape and lowercase only because there are accents into the urls I need to write. If your urls doesn't have accents, you can remove both.
If you want implement these redirects in php, here the code you need:
<?php
$dest_url = "http://example.com/path...";
header("HTTP/1.1 301 Moved Permanently");
header("Location: ".$dest_url);
Create a PHP page to operate as a 404 handler. It should inspect the incoming URL, check if it should map from an old page to a new page, then issue a 301. If there is no mapping then present a 404.
Simply set this page as the 404 handler in your .htaccess and there you go. IIRC this is how Wordpress used to handle 'clean' URLs on IIS before IIS7 brought in URL rewriting without needing a 3rd-party dll.
I have made a redirect class that is on the 404 page that will check the database if there is a valid page to 301 redirect to and redirect it instead of giving the 404 page. If it can't figure that out, it marks it in the database as a 404 page, so it can be fixed later.
Thanks for help guys. I've carried out the suggested course of action from freedev but have created a separate config file within Apache.
Within the httpd.conf file I have added:
# Map settings
Include "conf/extra/map.conf"
The map.conf file:
RewriteEngine On
RewriteEngine on
RewriteMap url_rewrite_map txt:conf/map.map
RewriteCond ${url_rewrite_map:$1|NOT_FOUND} !NOT_FOUND
RewriteRule ^(.*) http://website.com/${url_rewrite_map:$1} [R=301]
The map.map file is formatted as:
/oldname/ /newname
I've added quite a few of the urls for the redirection and so far so good, it isn't having a massive impact on the server like it did when added to .htaccess

Limiting Access to a subdirectory, httpd.conf access is not allowed, don't want to create htaccess apart from root directory

I researched for this quite a long time, but could not find proper answer.
I am using Free PHP Hosting website which is provided by 000webhost.com.
I have a .htaccess in public_html folder given by them.
directory structure has sub-directory such as includes which I dont want the users to if they directly go to URL, It should say Forbidden - 403.
I do not want .htaccess in every sub-directory where I do not want allow access.
I read somewhere that .htaccess can change behavior of all the subdirectories and itself.
I know performance wise it is not a good option, but I do not have access to httpd.conf.
I think on SO there are some answers which tells me this :
1. move those subdirectories outsides the public_html (do not want to do that)
2. create .htaccess for every subdirectories and denying access (which is pain and not a scalable solution)
3. Use rewrite rules (Could be a solution not sure)
I hope someone can understand and help me out.
Thanks a lot.
Really, the most secure solution is to move those directories outside the DocumentRoot. However, you can easily add rewrite rules in your one .htaccess to forbid access:
RewriteEngine On
# Group many forbidden directories as (a|b|c|d)
RewriteRule ^(include|otherforbidden|someotherone) - [F]
Unless you have dozens of directories downstream to manage though, I don't see a big problem with dropping a directory-specific .htaccess in each.
add RedirectMatch 403 ^/includes/.*$ to your root .htaccess file to redirect any calls to the /includes directory to force a 403 Forbidden error.
However, it would be safer to use RedirectMatch 404 ^/includes/.*$ instead because attackers will get a 404 File Not Found error instead. This is considered safer because the 403 error let's attackers know that there is a file to attack.

deny direct access to a folder and file by htaccess

Here is the scenario:
There is a index.php file in root folder
some files are included in index.php which are in the includes folder.
1 other file (submit.php) is in the root folder for form submit action.
I want to restrict direct user access to the files in includes folder by htaccess. also for submit.php. But include will work for index.php file.
Like, if user types www.domain.com/includes/somepage.php, it will restrict it (may be redirect to a error page).
I would just move the includes folder out of the web-root, but if you want to block direct access to the whole includes folder, you can put a .htaccess file in that folder that contains just:
deny from all
That way you cannot open any file from that folder, but you can include them in php without any problems.
This is pure mod_rewrite based solution:
RewriteRule ^(includes/|submit\.php) - [F,L,NC]
This will show forbidden error to use if URI contains either /includes/ or /submit.php
It's possible to use a Files directive and disallow access to all files, then use it again to set the files that are accessible:
<Files ~ "^.*">
Deny from all
</Files>
<Files ~ "^index\.php|css|js|.*\.png|.*\.jpg|.*\.gif">
Allow from all
</Files>
1 liner mod_alias based solution :
RedirectMatch 403 ^/folder/file.php$
This will show forbidden error for /folder/file.php
If I understand correctly you just want to deny access to the includes folder?
An .htaccess with a 'DENY FROM ALL' directive placed in the includes folder would do the trick.
Your Q comes in two parts, both jeroen and anubhava's solutions work for part I -- denying access to /includes. anubhava's also works for part II. I prefer the latter because I use a DOCROOT/.htaccess anyway and this keeps all such control in one file.
However what I wanted t discuss is the concept of "denying access to submit.php". If you don't want to use submit.php then why have it in DOCROOT at all? I suspect that the answer here is that you use it as a action target in some forms and only want it to be fired when the form is submitted and not directly , e.g. from a spambot.
If this is true then you can't use anubhava's part II as this will cause your form to fail.
What you can do here is (i) with the .htaccess check to ensure that the referrer was your own index page:
RewriteCond %{HTTP_REFERRER} !=HTTP://www.domain.com/index.php [NC]
RewriteRule ^submit\.php$ - [F]
And (ii) within your PHP index.php form generator include some hidden fields for a timestamp and validation. The validation could be, say, the first 10 chars of an MD5 of the timestamp and some internal secret. On processing the submit you can then (i) validate that the timestamp and validation match, and (ii) the timestamp is within, say, 15 minutes of the current time.
This you can prevent spamming as the only practical way that a spammer could get a valid timestamp / validation pair would be to parse a form, but this scrape would only have a 15 minute life.
Depending on possible other options set at a higher level you may need to put the following in your .htaccess file in your includes directory:
Satisfy all
Order deny,allow
Deny from all
I ran into this when the upper directory defined basic authentication including the line:
Satisfy any
This was preventing my deny from all to take effect because the users were authenticated.
You can add the below command to .htaccess file
Deny from all
ErrorDocument 403 "nothing is here"
It will display the "nothing is here" message in case of the unauthorised access.
If you want to redirect by an error code to a certain page then you can define a command as follows:
ErrorDocument 404 "/errors/404.html"
It will redirect to the /errors/404.html and show the custom page not found screen.

Categories