Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deny ajax file access using htaccess

There are some scripts that I use only via ajax and I do not want the user to run these scripts directly from the browser. I use jQuery for making all ajax calls and I keep all of my ajax files in a folder named ajax.

So, I was hoping to create an htaccess file which checks for ajax request (HTTP_X_REQUESTED_WITH) and deny all other requests in that folder. (I know that http header can be faked but I can not think of a better solution). I tried this:

ReWriteCond %{HTTP_X_REQUESTED_WITH} ^$
ReWriteCond %{SERVER_URL} ^/ajax/.php$
ReWriteRule ^.*$ - [F]

But, it is not working. What I am doing wrong? Is there any other way to achieve similar results. (I do not want to check for the header in every script).

like image 360
Vikash Avatar asked Aug 12 '10 10:08

Vikash


3 Answers

The Bad: Apache :-(

X-Requested-With in not a standard HTTP Header.

You can't read it in apache at all (neither by ReWriteCond %{HTTP_X_REQUESTED_WITH} nor by %{HTTP:X-Requested-With}), so its impossible to check it in .htaccess or same place. :-(

The Ugly: Script :-(

Its just accessible in the script (eg. php), but you said you don't want to include a php file in all of your scripts because of number of files.

The Good: auto_prepend_file :-)

  • But ... there's a simple trick to solve it :-)

auto_prepend_file specifies the name of a file that is automatically parsed before the main file. You can use it to include a "checker" script automatically.

So create a .htaccess in ajax folder

php_value auto_prepend_file check.php

and create check.php as you want:

<?
if( !@$_SERVER["HTTP_X_REQUESTED_WITH"] ){
        header('HTTP/1.1 403 Forbidden');
        exit;
}
?>

You can customize it as you want.

like image 191
Ehsan Avatar answered Oct 23 '22 15:10

Ehsan


I'm assuming you have all your AJAX scripts in a directory ajax, because you refer to ^/ajax/.php$ in your non-working example.

In this folder /ajax/ place a .htaccess file with this content:

SetEnvIfNoCase X-Requested-With XMLHttpRequest ajax
Order Deny,Allow
Deny from all
Allow from env=ajax

What this does is deny any request without the XMLHttpRequest header.

like image 18
dyve Avatar answered Oct 23 '22 14:10

dyve


There are only a few predefined HTTP_* variables mapping to HTTP headers that you can use in a RewriteCond. For any other HTTP headers, you need to use a %{HTTP:header} variable.

Just change

ReWriteCond %{HTTP_X_REQUESTED_WITH} ^$

To:

ReWriteCond %{HTTP:X-Requested-With} ^$
like image 1
Jonathan Amend Avatar answered Oct 23 '22 15:10

Jonathan Amend