No system is foolproof. Score! What you can do is add sequential layers of protection.
- Verify how the request was made
You've already researched and figured out how to do it, but the way you did it is not exactly the most appropriate, programmatically, because you suppress an error rather than deal with it.
Also, you assume a specific case for comparison, which is not certain since there are several JS frameworks that, assuming they send this header automatically, can suddenly, capitalize some letters differently, for example.
That said:
function isXmlHttpRequest() {
$header = ( array_key_exists( 'HTTP_X_REQUESTED_WITH', $_SERVER ) ?
$_SERVER['HTTP_X_REQUESTED_WITH'] : '' );
return ( strcmp( $header, 'xmlhttprequest' ) == 0 );
}
if( ! isXmlHttpRequest() ) {
// Acesso negado
}
Lately here in SOpt a lot has been said about controlling the origins of an XHR. AJAX is not crossdomain, but may turn out to be because of a misconfigured server. Better safe than sorry:
header("Access-Control-Allow-Origin: http://www.domain.com");
The most recommended way is to append to the request URL some random value which you, and only you can validate.
This can be from an MD5 hash of a uniqid () stored in session, despite what if you are EVEN interested in violating your application sessions can be captured. I do not go into details because I do not know exactly how this is done.
Or token "for real", which may even come from the same uniqid () but encrypted with a standard algorithm (things of RIJNDAEL 256 bits or more), stored in a database associated with the user ID, of short duration, being regenerated constantly.
SSL should come first, but whether for acquisitive availability or deployment complexity, I left it last. ;)