javascript - Why blocking direct url access also demolishes Ajax call from a file on the webserver?

542

I want to block Url (external) access to PHP file in the folder "/mi-php/". So I created a .htaccess file within /mi-php folder with the following codes:

<Files *.php>
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</Files>

Sure, the php files are blocked from directly url access. However, when I try to call this php (/mi-php/jobdata.php) file using Ajax in one file on the webserver as follows:

$(document).ready( function () { $.getJSON("/mi-php/jobdata.php", function(data){ etc etc

It is also blocked. I thought calling by another file under the same website root directory is considered "localhost" access. I guess I am wrong. But how to make the php file accessible to only my own files under the root directory?

252

Answer

Solution:

I don't see that there are any bullet proof ways of solving this. The only way I can think of is to see if the call is an Ajax call.

if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
    die();
}

Based on David Walsh blog post here.

You need to add the above snippet in the top of each file you're trying to block. There are two things to consider.

  1. Anyone can modify the header of their call and add the above header.
  2. Some servers/ajax-clients don't send this header (Apache and jQuery does).

There might be more you can check in your script but this would be a start.

154

Answer

Solution:

The method I suggested in the comment would be like:

RewriteEngine On

RewriteCond %{HTTP_REFERER} !^$ 
RewriteCond %{HTTP_REFERER} !^http://(www\.)?arvixe\.com/ [NC] 
RewriteRule ^mi-php(/|$) - [F,NC]

The above will go in the document root of your httpd server.

Note that a client can send fake headers to bypass these. Also, as Magnus suggests, these values might get removed from the request entirely pertaining to users' firewall/ISP settings. Do not rely 100% on this.


Another method you can try is, right before the AJAX call, store the following piece of value inside a session variable:

<?php $_SESSION['ajax'] = 'allowed';

Now, in the files that will be requested with AJAX call, put the following check at the very beginning of each of them:

<?php
    session_start();
    if( !isset($_SESSION['ajax']) and $_SESSION['ajax'] !== 'allowed' )
        die();
    else
        unset( $_SESSION['ajax'] );
?>

People are also looking for solutions to the problem: PHP Switch not outputting.

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.