How could I be sure that my php has been invoked by my javascript posted on my web page only and from an authenticated user only? I would like to prevent attacks or data-stealing from other web sites or other unauthorized users who e.g. could invoke my php script and get/delete some of my data without the permission. As I know $_SERVER['HTTP_REFERER'] could be easily changed so it's not reliable so I can't be sure that my php has been invoked from my javascript on my web page. The Cookies are not reliable too, so I can't be sure that the userID that I stored in the cookies as an authorized user who properly logged in, hasn't been craked and changed. So how to make a javascript/php web app safe? Any suggestion? Thank you.
Take a look at How do I provide more security for checking source of the request.
It sounds like you are afraid of Cross-Site Request Forgery (CSRF) on your site. Follow the link to learn more about CSRF.
As a rule of thumb you always do your security backend. Below is an example of a secret handshake method you can use.
This method guarantees that the user has at least started his series of request by knowing the first secret:
Generate a unique value for the user in PHP and make it a hash of something unique to the user that you can easily recreate:
$secretHandshake = hash('sha512', $user_id . '_' . $secret_counter);
Put this somewhere on your site where JavaScript can get it. A hidden input field is good for this.
Now when you AJAX, simply submit the secret
with the AJAX as a parameter:
var secret = jQuery("#secret").val();
jQuery.ajax({
url: "doStuff.php",
method: "POST",
data: {action: 'createUser', data: /* whatever */, secret: secret}
}).success(function(response) {
//Save the new secret
response = JSON.parse(response);
secret = response.secret;
});
Now we can simply validate the request on the server:
if(!isset($_POST['secret']) || /* User not logged in check */) {
die();
}
if($_POST['secret'] === $secretHandshake) {
//Now that we have validated the respone, we create a new secret
$secret_counter++;
$secretHandshake = hash('sha512', $user_id . '_' . $secret_counter);
$returner = array('secret' => $secretHandshake);
//Do something with the data
//Append extra responses if relevant:
$returner['data'] = 'Success!';
//Return as json for JavaScript
echo json_encode($returner);
}
This makes it harder for bots to attack your site since the must know the current secret for each request.