views:

62

answers:

4
+1  Q: 

AJAX Security Help

Hello Everyone,

I have an AJAX Function that calls a PHP Script and displays the result on a page.

So, i have two pages, say:

form.php - This is where the Input is gathered and displayed process.php - This is the php that is called and result from this is displayed on form.php

Now, here is my AJAX Function:

function showList(str)
{
if (str=="")
{
document.getElementById("message").innerHTML="";
return;
}
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("message").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","process.php?q="+str,true);
xmlhttp.send();
}

As you can clearly see that value gathered from the form is passed to process.php as follows:

process.php?q=1

With each query string, a list is pulled from the database. The same list can also be pulled in by typing the domain.com/process.php?q=1,2,3, or so forth...

My question is, how can i fix this loop hole so that requests coming from only my script have access to process.php and no one else?

Thanks in advance!

+2  A: 

You could simply check the HTTP_REFERER variable ($_SERVER['HTTP_REFERER']), but that could be spoofed...

If you want it to be more secure, you could generate limited-use tokens. The Ajax call would also send the token, and it would be validated (and expired) on the server side.

Fosco
+1  A: 

You cant, really. Not 100% reliably. But, AJAX requests also send you the domain's cookie values, so if you have an application that requires a user to log on, you can check that the requester is part of a valid a session w/ your application, just like you would for any other page in the app.

GrandmasterB
Yes, i am already maintaining sessions for my pages, how do i do the same with Ajax?
Jasdeep Singh
@Jasdeep you would check in process.php. It's not really related to Ajax.
Fosco
@Jasdeep, you dont do anything special... just handle reading the session info like all other page loads. As far as php knows, its just a regular page request. If its done this way, it doesnt matter where the php file is called from, because a valid session wouldbe required for it to return any information. So you dont have to mess around with checking referrers.
GrandmasterB
@GrandmasterB, will try that and update! Thanks!
Jasdeep Singh
A: 

You could also check for the HTTP_X_REQUESTED_WITH header in the $_SERVER variable:

if(isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
    $requestedwith = strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) ;
    if($requestedwith === "xmlhttprequest") {
        // Requested by Ajax
    }
}

Again, this could be spoofed too though.

Gus
Is there a fool-proof method to secure Ajax Apps?
Jasdeep Singh
No. By default, you are uploading source code (javascript) to a browser. What happens to it there is out of your control.
Gus
Thanks! Craig Edmunds solution above seems more promising.. Will have to rely on HTTP_X_REQUESTED_WITH method if i'm unable to find source code for PHP CSRF guard
Jasdeep Singh
+1  A: 

When you render form.php render a hidden input with a random sequence as the value (easiest option is a guid). Store that string either in the users cookie (encrypted) or in server side session state. Whenever you render the form, render a new key.

Then send this value to process.php and in process.php compare the two values.

It's called an "Anti forgery token" - there's detail on the .net implementation here http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/, there's probably a similar mechanism for php.

Craig Edmunds
Here's a reference from the web security project about the vulnerability http://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
Craig Edmunds
I stumbled upon the same website right after reading your code.. But there seems to be no Downloads available for this Library that i can include in my scripts.. Still searching
Jasdeep Singh
It's pretty simple to write yourself, literally generate a random string and store it in session. If you're not using session state then hash it and put it in a cookie. Render it in the form as a hidden input.
Craig Edmunds
Sorry; when servicing an incoming request first check this form field.
Craig Edmunds