[ACCEPTED]-Detecting Ajax in PHP and making sure request was from my own website-security
Let you Controller
- generate access token
- store in session for later comparison
In your View
- declare the access token as JS variable
- send the token with each request
Back in your 2 Controller
- validate HTTP_X_REQUESTED_WITH
- validate token
Check these security guidelines from OpenAjax.
Also, read 1 the article on codinghorror.com Annie linked.
You can check the HTTP_REFERRER, but not 9 all browsers set it. The best way is to 8 write a wrapper for your ajax calls on the 7 JavaScript side which sends part of document.cookie 6 back to the server--only your domain has 5 access to the cookie. You can compare the 4 cookie in the request headers with the cookie 3 in the AJAX call in php.
In response to, "does 2 it even matter, these days"--YES, it 1 does! Read this.
Regarding your last question: "Does 21 it even matter, in these days?" This 20 is a case by case question. If the ajax 19 request is doing something that does not 18 require security (e.g. loading latest stock 17 quotes) then it really doesn't matter IMHO. If 16 the request is loading information that 15 should be secured (e.g. returning identifying 14 information or doing something on the server) then 13 you should treat it as such.
I personally 12 don't use the server variables to know when 11 something is an ajax request. Instead I 10 just add a query parameter to the ajax call 9 (e.g. http://domain.com/?ajax=true). If I need to secure the ajax call 8 then I would use the same methods as securing 7 a regular page request (using both client 6 and server). As Lucas Oman pointed out, anything 5 on the client side can be faked. Bottom 4 line don't trust any request even if you 3 think it is coming from your site or database. Always 2 follow the mantra "filter input - escape 1 output".
David Walsh has a good solution
/* decide what the content should be up here .... */
$content = get_content(); //generic function;
/* AJAX check */
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
/* special ajax here */
die($content);
}
/* not ajax, do more.... */
0
Really, the most secure way to do this is 12 to, as you suggested, use server-side sessions, as 11 these cannot be crafted as cookies can.
Granted, someone 10 can still hijack a session ID, but if you 9 also store the user's IP address in their 8 session and check it on each request, you 7 can weed out a lot of hijacks. Only someone 6 on the same LAN or proxy could hijack it.
Any 5 other method mentioned--cookies, javascript, http 4 referer--depends on client-side data, which 3 is insecure and should always be suspected 2 of being fake, forged, hijacked and maliciously 1 constructed.
Use POST session secured requests:
Inside the Webpage (e.g. index.php) we need to store the sessionid
<?php
// Create Session
$session = session_id();
if(empty($session)) session_start();
?>
<head>
...
<script type="text/javascript">
sid = '<?php echo session_id(); ?>';
</script>
<script type="text/javascript" src="ajaxrequest.js"></script>
...
</head>
The ajax requests (ajaxrequest.js)
/* simple getAjax function
* @param $url request url
* @param $param parameter (dont use ?)
* @param callback function on success
*/
var spinnerid = '#spinner'; // Spinner as long ajax requests running
$(document).ajaxStart(function() { $(spinnerid).show(); });
$(document).ajaxStop(function() { $(spinnerid).hide(); });
function getAjax( url, param, callback ) {
var data = null;
url += "?sid=" + sid + "&" + param;
$.ajax({
url: url,
method: "POST", // uncomment to use GET, POST is secured by session
cache: false,
async: true,
success : function(data){
callback(data);
},
}
getAjax( 'http://domain.com/', 'data=foo', function( data ) {
// do stuf with data
var jsonobj = eval("(" + data + ")");
var data = jsonobj[0][ 'data' ];
});
Responsible 1 php side:
if( isset( $_GET['sid'] ) ) $client_sid = $_GET['sid'];
if( session_id() == null ) session_start();
if( session_id() != $client_sid ) {
// noID or wrongID, redirect to mainindex
ignore_user_abort(true);
header( "HTTP/1.1 403 Forbidden" );
header("Connection: close", true);
exit;
} else {
// get data
if( isset( $_GET['data'] ) ) {
$data = $_GET['data'];
} else if( isset( $_POST['data'] ) ) {
$data = $_POST['data'];
} else {
$data = null;
}
// do stuff with data
// return data as json
$resp[0]['data'] = $data;
print_r( json_encode( $resp ) );
}
Check the $_SERVER['HTTP_REFERER']
. This will work in many cases, but 2 shouldn't be confused for a completely-secure 1 solution.
Use google recaptcha... It generates a token 2 for your Ajax then on the server side you 1 can verify the token...
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.