PHP的网站安全问题? (也可能适用于ASP / Rails /等..)

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

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:

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.

Use the HTTP_REFERER server variable:

echo $_SERVER['HTTP_REFERER']

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

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

(So: no need to worry.)

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.

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.