Prevent Direct Url Access to PHP File

Prevent direct access to a php include file

The easiest way for the generic "PHP app running on an Apache server that you may or may not fully control" situation is to put your includes in a directory and deny access to that directory in your .htaccess file. To save people the trouble of Googling, if you're using Apache, put this in a file called ".htaccess" in the directory you don't want to be accessible:

Deny from all

If you actually have full control of the server (more common these days even for little apps than when I first wrote this answer), the best approach is to stick the files you want to protect outside of the directory that your web server is serving from. So if your app is in /srv/YourApp/, set the server to serve files from /srv/YourApp/app/ and put the includes in /srv/YourApp/includes, so there literally isn't any URL that can access them.

prevent direct url access to php file

You can do it with PHP

<?php
/* at the top of 'check.php' */
if ( $_SERVER['REQUEST_METHOD']=='GET' && realpath(__FILE__) == realpath( $_SERVER['SCRIPT_FILENAME'] ) ) {
/*
Up to you which header to send, some prefer 404 even if
the files does exist for security
*/
header( 'HTTP/1.0 403 Forbidden', TRUE, 403 );

/* choose the appropriate page to redirect users */
die( header( 'location: /error.php' ) );

}
?>

Prevent direct access to a php file but allow including it

Here are two options you could give a try:

<?php
/**
* Returns true if current file is included
*/

function isIncluded() {
$f = get_included_files();
return $f[0] != __FILE__;
}

if(!isIncluded()) {
// Do some stuff, eg: print some HTML
} else {
// Show 403/error
}

?>
<?php

// You can also use (recommended)
if(__FILE__ !== $_SERVER["SCRIPT_FILENAME"]) {
// this file is being included
}

?>

You may also opt to put the files into a directory protected by a .htaccess and a Deny from all since PHP can bypass that, but users cannot.

prevent direct URL access to php and html pages via .htaccess

This .htaccess file will only allow users to open index.php. Attempts to access any other files will result in a 403-error.

Order deny,allow
Deny from all

<Files "index.php">
Allow from all
</Files>

If you also want to use authentication for some of the files, you may simply add the content from your current file at the end of my example.

Prevent direct access to a webpage by typing the URL

so your login screen should already have session code implemented into it that has a variable that specifies if the user is logged in or not. If you don't have that implemented yet, the code would look similar to:

<?php session_start();//at the very top of the page
?>
//... your own code
//if the user successfully logs in then:
$_SESSION['authenticated']=true;

Then on the booking.php page (it should be php to allow php scripts which is super important for validating if a user is logged in), you would then check if the user did log in. If he did, the rest of the page loads, if he didn't, you would redirect them to login.php:

at the very top of booking.php:

<?php session_start();
if (!isset($_SESSION['authenticated']))
{
//if the value was not set, you redirect the user to your login page
header('Location https://www.example.com/login.php');
exit;
}
else
{
//if the user did login, then you load the page normally
}

prevent direct url access

Apache: Add the line below in your root .htaccess file

Options -Indexes

If there is a line Options Indexes already in existing .htaccess file than you can simply modify it with Options -Indexes

This will have Apache preventing direct directory access.

How to prevent direct access to a php page but can be accessed when redirected

Everything up to this working very fine...

Actually, I don't think it is...

...prevent direct access to a php page but can be accessed when redirected

This isn't just any PHP page. It is your 404 "Not Found" error document.

You should not be externally 3xx redirecting to your error document in the first place. The error document should be served in the same request (an "internal subrequest"). This is the root cause of your problem.

The redirected request is an entirely separate request, mostly indistinguishable from a "direct request", which will naturally make reliably blocking direct requests "impossible". However, do you really need to block "direct requests" to your 404 error document? (See below...)

ErrorDocument 404 http://localhost/news_21_off/404.php

By specifying an absolute URL (ie. with a scheme + hostname) in the ErrorDocument directive, Apache will trigger a 302 external redirect to the stated URL. The user sees a 302 response (not a 404), followed by a 200 "OK" (not a 404) from the redirected request, unless you manually send the 404 "Not Found" status in your PHP code (there is no evidence of that here).

Just because Apache allows you to "redirect" to the error document, doesn't mean you should. As noted in the Apache docs:

Note that when you specify an ErrorDocument that points to a remote URL (ie. anything with a method such as http in front of it), Apache HTTP Server will send a redirect to the client to tell it where to find the document, even if the document ends up being on the same server. This has several implications, the most important being that the client will not receive the original error status code, but instead will receive a redirect status code. This in turn can confuse web robots and other clients which try to determine if a URL is valid using the status code.

In addition, all the helpful PHP superglobals (passed from Apache) that ordinarily relate to the URL that triggered the 404 are lost (eg. $_SERVER['REDIRECT_STATUS'], $_SERVER['REDIRECT_URL'], etc.) because, as mentioned above, the redirected request is an entirely separate request.

99.99% of the time you should be using a root-relative URL-path in the ErrorDocument directive, so that Apache triggers an internal subrequest for the error document, for example:

ErrorDocument 404 /news_21_off/404.php
header('location:404.php');

Likewise, you should not be "redirecting" to your error document in your PHP code either.

In PHP, there are various ways to resolve this. You could simply include() the error document at the point in your code you wish to serve the 404.

For example, in your products.php script:

<?php
$pid = $_GET['pid'] ?? null;
if ($pid == '4') {
echo 'correct';
} else {
// 404 Not Found
include($_SERVER['DOCUMENT_ROOT'].'/news_21_off/404.php');
exit();
}

However, the above won't send a 404 HTTP status code to the client. In your PHP 404 error document you should set the HTTP status to ensure that a 404 status is sent by PHP and when/if the document is accessed directly by the user.

For example, in your 404.php script:

<?php
http_response_code(404);
?>
<h1>My 404 page</h1>

Incidentally, setting the HTTP status code in your PHP script will override any status that Apache might have set when serving an error document.

Now, back to your initial question...

I want to prevent direct access to my error page which is 404.php

Why?

Having implemented the changes above, if a user does "directly access" your 404 error document they are simply served a 404 and see the same response as if they had requested any other document that didn't exist.

So, unless you have a specific requirement, there is nothing more you need to do here.



Related Topics



Leave a reply



Submit