2

I'm trying to deny direct url access to a php file that is called upon ajax for form validation. The code I currently have works up until the form is validating, which then it doesn't work. I DON'T want to use .htaccess.

Current code:

<?php

$url = strtolower(basename($_SERVER['PHP_SELF'])); // Gets url (parent that uses the include)
$fil = strtolower(basename(__FILE__)); // gets filename (the included file)
if ($url == $fil){
    // if they are the same (file is accessed through url
    // redirect to forbidden page
    header("HTTP/1.0 403 Forbidden");
    exit;
}
// require my configuration
require_once("config.php");
// code to be executed for ajax validation
$username = $_POST['username'];
$conn = mysql_connect(DB_HOST,DB_USER,DB_PASS) or die(mysql_error());
mysql_select_db(DB_NAME,$conn) or die(mysql_error());

$query = mysql_query("SELECT * FROM " . TB_USER . " WHERE username = '{$username}'",$conn) or die(mysql_error());
$result = mysql_num_rows($query);

mysql_close($conn);

if ($result == 0){
    echo "true";
}else{
    echo "false";
}
?>

If I access the file directly from url, it redirects like planned, but when the form is being validated via ajax, it doesn't do anything if the username is unavailable. Taking out the first two lines of code ($url, $fil) as well as the if statement makes the ajax validation work, but the page is not denied on url access. Any suggestion on what to do from here?

Vince
  • 2,214
  • 9
  • 34
  • 66
  • This has been asked many times before - the "Related" box on the right of the screen pointed me at http://stackoverflow.com/questions/1756591/prevent-direct-access-to-file-called-by-ajax-function http://stackoverflow.com/questions/10637951/how-to-block-external-http-requests-securing-ajax-calls?lq=1 http://stackoverflow.com/questions/8278865/prevent-ajax-cheating-on-a-web-game?lq=1 http://stackoverflow.com/questions/7127686/blocking-non-ajax-requests-to-php?lq=1 http://stackoverflow.com/questions/8842053/allow-access-through-ajax-only-not-directly?lq=1 – IMSoP Apr 23 '13 at 20:39

2 Answers2

6

Use this:

if(!$_SERVER['HTTP_X_REQUESTED_WITH'])
{
   header("HTTP/1.0 403 Forbidden");
   exit;
}

In all modern browsers, if a page is accessed using AJAX, PHP adds this header to the request. If your page is being called and this header is not present there is a good chance it is being called directly (or by another page redirecting to it through a hyperlink or otherwise). Basically this always show the forbidden page unless this page was called using AJAX.

raidenace
  • 12,380
  • 1
  • 27
  • 33
  • 1
    Amazing. I was unaware of that functionality. Defiantly keeping that in my notes. – Vince Apr 23 '13 at 18:43
  • @Vince Do remember that headers can be spoofed. However currently this is one of the methods of examining the header to check if it is a (potential) ajax request. – raidenace Apr 23 '13 at 18:46
2

There is no point in doing this. It doesn't add any actual security.

All the headers that indicate that a request is being made via Ajax (like HTTP_X_REQUESTED_WITH) can be forged on client side.

If your Ajax is serving sensitive data, or allowing access to sensitive operations, you need to add proper security, like a login system.

Pekka
  • 418,526
  • 129
  • 929
  • 1,058
  • I'm not really looking for security, I just don't want the page viewable, as all it does is write to the page: true or false, depending on if a user exists or not. It's just a fun project I'm working on, that if I think it turns out really good, then I'll change my code for security. Right now, it's just being hosted on my local server :) – Vince Apr 23 '13 at 18:47
  • 1
    Just saying because so many people actually think they can substitute this for real security in serious projects.... – Pekka Apr 23 '13 at 18:50
  • I know, if I really want something secure, I'll make sure if it, for example, when storing passwords, I have a random number chosen and it cycles through md5 and sha1 a number of times until it reaches that number. – Vince Apr 23 '13 at 18:52
  • 1
    If not for security, why do you care? They can load it, just like they can load your JS and CSS includes, because that's how the web works. – IMSoP Apr 23 '13 at 18:55
  • 1
    I like to experiment with different techniques, expanding my knowledge of programming languages. – Vince Apr 24 '13 at 20:32