views:

132

answers:

6

Say, I have "index.htm" and "routines.php".

"index.htm" will call eventually call "routines.php" using JS (AJAX).

So, my question is, how can "routines.php" verify that the request came from the same local server and not outside? Is there a global variable I can check at PHP level or HTTP level?

Edit 1: Using AJAX

+1  A: 

If the call is made in JavaScript (i.e., on the client), you really can't do anything to definitely prevent someone from simulating a request from index.htm, even if you check the Referer (sic) header.

If the request is made on the server side, you could use some kind of key.

You can of course generate a key on the client side too, but this security measure can be imitated by anyone to simulate a request from index.htm.

Blixt
A: 

Use the HTTP_REFERER server variable:

echo $_SERVER['HTTP_REFERER']

With this you can know if the request comes from the server you want.

backslash17
It's very easy to spoof the HTTP Referer header.
Ionuț G. Stan
$_SERVER['HTTP_REFERER'] is bad practice. you can't safely relay on this information.
Philippe Gerber
It could stop http://en.wikipedia.org/wiki/Cross-site_request_forgery though?
Arjan
+2  A: 

To answer your question with another question: how would you invoke getdata() using a browser?

(So: no need to worry.)

Arjan
Forgot to mention, using AJAX :P
Atlas
still. when i open routines.php in my browser and the function is only defined in this file, nothing is gonna happen. and at the position where you call the function, you should have already verified whether the function can be called or not.
Philippe Gerber
yep, opening routines.php from any browser won't do anything. But what if, someone make a similar index.htm, and it calls getdata() from my routines.php, the request is considered valid, no?
Atlas
Even with Ajax you can only request routine.php, and not getdata() directly -- can you? Please show us some code then... But basically you cannot prevent someone from calling your Ajax methods. Even if you have some session and authentication in place, then still someone could first authenticate to get that session, and then invoke your Ajax calls. (We need more info for a detailed answer.)
Arjan
+3  A: 

You may forget about the Ajax part as it's not really part of the problem. You should read about Cross Site Request Forgeries (CSRF) and CSRF tokens. Some links:

Ionuț G. Stan
thanks, i'll check them out.
Atlas
A: 

As others pointed out, it would be pretty difficult given your original specification. However, if you can change the index.htm to be index.php and have it output the same content as index.htm, you can also put in additional tokens for session management (e.g. Cookies - yes I know they are easy to spoof too :) and reject the call to getdata() if the tokens don't match.

+1  A: 

you could use a session key:

index.htm

<?php

$_SESSION['safe_key'] = true;

?>
javascript code here

routines.php

<?php
if (!isset($_SESSION['safe_key'])) {
   die('from outside');
}

function getdata() { ... }
?>

Basically what happens is when index.htm is called a session safe key is created. Sessions are serverside only. In routines.php if the safe key does not exist, the code was not called from index.htm. If it does exist, run code.

Ozzy
...still nothing prevents someone from sending the session cookie that is received by simply requesting index.html once.
Arjan
you could use session_regenerate_id() to stop that happening :)
Ozzy
...and then one would simply send that new cookie value (received when the Ajax call completes) along with the next request... :-) (Too bad we'll never know what Atlas was trying to avoid here.)
Arjan
I ment call session_regenerate_id after every request to routines.php :P
Ozzy
Yes, but then still the Ajax response would include the new cookie?
Arjan
Not quite. If the "hacker" gets ahold of the old session id, using it to request routines.php wont get it to send a new session id. Php will only send the new id once and that would be for the first and only request which would be done by index.php
Ozzy