Ajax detection in PHP and the certainty that the request was from my own site

I use my PHP server to detect AJAX requests by checking the value in $_SERVER['HTTP_X_REQUESTED_WITH'] .

This gives me reliable detection, making sure the request is executed using AJAX methods.

How can I make sure the request came from my own domain, and not from an external domain / robot?

www.example.com/ajax?true can let someone make an AJAX call and cut out the information.

I could do sessions for everyone who usually logs into my site and then resolves AJAX calls .. but that too can be faked.

Does it even matter these days?

+42
security ajax php
Dec 23 '09 at 16:50
source share
7 answers

Lets you controller

  • create access token
  • save in session for later comparison

In your view

  • declare an access token as a JS variable
  • send a token with each request

Back to your controller

  • check HTTP_X_REQUESTED_WITH
  • check token

Check out these security rules from OpenAjax .
Also, read the article about codinghorror.com related to Annie.

+31
Dec 23 '09 at 17:06
source share

You can check HTTP_REFERRER, but not all browsers have installed it. The best way is to write a wrapper for your ajax calls on the JavaScript side, which sends part of the .cookie document back to the server - only your domain has access to the cookie. You can compare the cookie in the request headers with the cookie in an AJAX call in php.

In response to this, β€œthis is even important these days” - YES, it is! Read this .

+23
Dec 23 '09 at 16:56
source share

Regarding your last question: β€œDoes it matter today?” This is a question in each case. If an ajax request does something that does not require security (for example, it downloads the latest stock quotes), then it really does not matter. IMHO. If the request downloads information that should be protected (for example, returning identifying information or doing something on the server), then you should consider it as such.

I personally do not use server variables to know when something is an ajax request. Instead, I simply add the request parameter to the ajax call (e.g. http://domain.com/?ajax=true ). If I need to protect the ajax call, I would use the same methods as providing a regular page request (using both the client and the server). As Lucas Oman noted, anything on the client side can be tampered with. The bottom line does not trust any request, even if you think that it comes from your site or database. Always follow the mantrams "filter input" - output output.

+6
Dec 23 '09 at 17:51
source share

David Walsh has a good decision

 /* 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.... */ 
+3
Dec 23 '09 at 17:00
source share

Indeed, the safest way to do this is, as you suggested, to use server-side sessions, as they cannot be created as cookies.

Of course, someone can still grab the session ID, but if you also save the IP address of the user in your session and check it for every request, you can snatch a lot of tricks. Only someone from the same local network or proxy server could capture it.

Any other method mentioned - cookie, javascript, http referer - depends on client-side data, which is unsafe and should always be suspected of forgery, fake, hijacking and malicious construction.

+2
Dec 23 '09 at 17:46
source share

Use secure POST session requests:

Inside the webpage (e.g. index.php) we need to save 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> 

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' ]; }); 

The responsible side of php:

 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 ) ); } 
+1
Feb 12 '16 at 20:49
source share

Check out $_SERVER['HTTP_REFERER'] . This will work in many cases, but should not be confused with a fully protected solution.

0
Dec 23 '09 at 16:51
source share



All Articles