How to Prevent Direct URL Access to PHP form files

Access denied

Let say we have a PHP file called form-contact.php in our website and it is executed when a form is submitted. The directory of the php file is in a folder named src/php/. One day, someone knows about the location of the php files from EMAIL HTTP HEADERS, that intentionally submitted when users filled a contact form and then send it.

He knows about that file path, and then he tried to access that file directly via web browser. For example;

https://mywebsite.com/src/php

The results from above request, potentially would cause a massive email spam from the php contact form file. Even though we do some Javascript validation to prevent the contact form for being empty filled. Our Inbox might be full of email consist of empty content (except the hardcoded one).

So how to prevent direct url access to form-contact php? If anyone types the url https://mywebsite.com/src/php, then the php file should not be executed and it should return error message instead.

There are two possible ways to run:

1. Put this code at the top of form-contact.php

form-contact.php
<?php
if ( $_SERVER['REQUEST_METHOD']=='GET' && realpath(__FILE__) == realpath( $_SERVER['SCRIPT_FILENAME'] ) ) {
header( 'HTTP/1.0 403 Forbidden', TRUE, 403 );
die( header( 'location: /error.php' ) );
}
?>

the header( ‘HTTP/1.0 403 Forbidden’, TRUE, 403 ); is the Header request and is up to you which header to send. Some prefer 404 even if the file does exist. I prefer to choose 403 Forbidden.

the die( header( ‘location: /error.php’ ) ); is the appropriate page to redirect users. In this case, I’ve created an error.php page below:

error.php
$status = $_SERVER['REDIRECT_STATUS'];
$codes = array(
403 => array('403 Forbidden', 'The server has refused to fulfill your request.'),
404 => array('404 Not Found', 'The document/file requested was not found on this server.'),
405 => array('405 Method Not Allowed', 'The method specified in the Request-Line is not allowed for the specified resource.'),
408 => array('408 Request Timeout', 'Your browser failed to send a request in the time allowed by the server.'),
500 => array('500 Internal Server Error', 'The request was unsuccessful due to an unexpected condition encountered by the server.'),
502 => array('502 Bad Gateway', 'The server received an invalid response from the upstream server while trying to fulfill the request.'),
504 => array('504 Gateway Timeout', 'The upstream server failed to send a request in the time allowed by the server.'),
);
$title = $codes[$status][0];
$message = $codes[$status][1];
if ($title == false || strlen($status) != 3) {
$message = 'Please supply a valid status code.';
}
echo '<h1>'.$title.'</h1>
<p>'.$message.'</p>';

or if you prefer to create a way more simpler approach, you can do this:

error.php
<?php
if ( $_SERVER['REQUEST_METHOD']=='GET' && realpath(__FILE__) == realpath( $_SERVER['SCRIPT_FILENAME'] ) ) {
header( 'HTTP/1.0 403 Forbidden', TRUE, 403 );
die ("<h2>Access Denied!</h2> This file is protected and not available to public.");
}
?>

So when a user access form-contact.php by typing the URL directly, it will appear error page like this:

Access denied

2. Modifying file .httaccess

Another way you can try is, modify the .htaccess file like this;

.httaccess
RewriteEngine on


RewriteCond %{REQUEST_METHOD} !^POST$
RewriteRule ^php/check.php$ - [NC,R=404,L]

This will return 404 not found if form-contact.php is not accessed by form post method.

I found that the above ways worked as I wanted. Just add that code on top of every file you would want to block direct URL access and you’re good to go.

I could be wrong of course, and if you have any solutions or there’s a flaw from above approaches, don’t hesitate to share your solutions.

Email icon representing an email newsletter

Don't subscribe