0

I'm making an AJAX call from example.com/js/script.js to example.com/inc/ajax.php and need to deny direct access to the PHP file if a user tries accessing it directly via their browser.

The accepted answer here suggests checking a HTTP header. The problem with that approach is headers can be easily spoofed.

How can check if an AJAX-called PHP file has been accessed directly and provide a 403 Forbidden response?

Community
  • 1
  • 1
henrywright
  • 9,235
  • 22
  • 77
  • 139
  • if you dont trust the header - you cant. the joy of stateless protocols. – Rufinus May 18 '15 at 21:26
  • If it's an AJAX call then it is coming from the clients browser, always. Java script executes on the client end. – greg_diesel May 18 '15 at 21:27
  • Why would you bother? If your website's page can get the result, then the user *can always see* what the response is simply by looking at the network tag of their dev tools. Just keep it a normal URL. Instead, can you explain why you think this is even a sensible idea? (e.g. what is in that file that you don't want people to find, but do want to be XHRable? Because those two things are kind of mutually exclusive) – Mike 'Pomax' Kamermans May 18 '15 at 21:28
  • Route the request through your main application and deny all direct access to `/inc`? Use `include`? – Wesley Murch May 18 '15 at 21:29
  • +greg_diesel you really think i cant "fake" such a request to his ajax.php ? its just a get call with some headers. – Rufinus May 18 '15 at 21:29
  • 1
    you could set/remove a session variable that your php script checks for the presence of? – STLMikey May 18 '15 at 21:29
  • Is this actually a security concern? Can you explain how? It might reveal deeper problems. – Wesley Murch May 18 '15 at 21:30
  • 1
    @Rufinus I think you misunderstood by comment. My point is the request is always coming from the client. Meaning the client will always be able to access that data. – greg_diesel May 18 '15 at 21:30
  • 1
    If you're doing it right your ajax call should include some parameters, so that if the user just goes to ajax.php (no parameters) absolutely nothing happens. – developerwjk May 18 '15 at 21:31
  • @greg_diesel true, true. it seems he is trying to achieve some security by obscurity.... which never works. – Rufinus May 18 '15 at 21:32
  • I don't have a specific security concern in mind; instead, I was just interested if this was at all possible. – henrywright May 18 '15 at 21:33
  • the "problem" with HTTP is, its stateless, and with all benefits it has, this is one of the downsides. each request is a request on its own... and doesnt now anything about other requests. (sessions are just a way to get around exactly that problem) – Rufinus May 18 '15 at 21:34
  • @WesleyMurch routing the request through my main application sounds an interesting idea. Any chance you could explain in a little more detail? – henrywright May 18 '15 at 21:38
  • For example, making the request to index.php or whatever, checking the parameters, and including the appropriate file from `/inc` to output the response. I mean it really doesn't solve anything, but your concern is not particularly clear. I don't know why someone would end up making a direct request in their browser to one of your ajax handlers unless you are linking to it. – Wesley Murch May 18 '15 at 22:12

1 Answers1

1

Since each AJAX request is a normal browser request that happens in the background, it could be analyzed and reproduced with the developer-tools most browser provide.

The only thing i can think of is an one-time-token that you send with your ajax request that get validated and destroyed serverside. but even that could be tricked at some point.

Jan
  • 2,744
  • 2
  • 18
  • 25
  • Passing a token is a good idea, best alternative I've heard yet. Agreed it also can be spoofed – henrywright May 18 '15 at 21:36
  • create a .htaccess in folder where ajax file is saved with below value php_value auto_prepend_file check.php 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. and create check.php as you want: if( !@$_SERVER["HTTP_X_REQUESTED_WITH"] ){ header('HTTP/1.1 403 Forbidden'); exit; } ?> This is just a way to avoid direct hit, and can be spoofed though with tools. – akmsharma May 18 '15 at 21:44