views:

234

answers:

8
+1  Q: 

Ajax Security

We have a heavy Ajax dependent application. What are the good ways of making it sure that the request to server side scripts are not coming through standalone programs and are through an actual user sitting on a browser

A: 

Interesting question.

What about browsers embedded in applications? Would you mind those?

You can probably think of a way of "proving" that a request comes from a browser, but it will ultimately be heuristic. The line between browser and application is blurry (e.g. embedded browser) and you'd always run the risk of rejecting users from unexpected browsers (or unexpected versions thereof).

Assaf Lavie
+5  A: 

There aren't any really.

Any request sent through a browser can be faked up by standalone programs.

At the end of the day does it really matter? If you're worried then make sure requests are authenticated and authorised and your authentication process is good (remember Ajax sends browser cookies - so your "normal" authentication will work just fine). Just remember that, of course, standalone programs can authenticate too.

blowdart
+1  A: 

Is Safari a webbrowser for you?
If it is, the same engine you got in many applications, just to say those using QT QWebKit libraries. So I would say, no way to recognize it.

User can forge any request one wants - faking the headers like UserAgent any they like...

One question: why would you want to do what you ask for? What's the diffrence for you if they request from browser or from anythning else?
Can't think of one reason you'd call "security" here.

If you still want to do this, for whatever reason, think about making your own application, with a browser embedded. It could somehow authenticate to the application in every request - then you'd only send a valid responses to your application's browser.
User would still be able to reverse engineer the application though.

kender
+2  A: 

What are the good ways of making it sure that the request to server side scripts are not coming through standalone programs and are through an actual user sitting on a browser

There are no ways. A browser is indistinguishable from a standalone program; a browser can be automated.

You can't trust any input from the client side. If you are relying on client-side co-operation for any security purpose, you're doomed.

bobince
A: 

Well there isn't any technique that tells you with 100% accuracy that whether a request is coming from a standalone program and through a user using a browser. Remember that "standalone program" could itself be a browser.

I believe it is possible to access "Sessions" in pages that are accessed through AJAX. Most browsers should pass the session-mapping cookie along with AJAX request. You might be able to (and should) use this information if you require the user to login through a web interface. Or you might present the user with a CAPTCHA challenge first, and if it succeeds you can store an "OK" flag in the session and serve further AJAX requests.

Salman A
A: 

As been mentioned before there is no way of accomplishing this... But there is a thing to note, useful for preventing against CSRF attacks that target the specific AJAX functionality; like setting a custom header with help of the AJAX object, and verifying that header on the server side.

And if in the value of that header, you set a random (one time use) token you can prevent automated attacks.

+1  A: 

I'm not sure what you are worried about. From where I sit I can see three things your question can be related to:

First, you may want to prevent unauthorized users from making a valid request. This is resolve by using the browser's cookie to store a session ID. The session ID needs to tied to the user, be regenerated every time the user goes through the login process and must have an inactivity timeout. Anybody request coming in without a valid session ID you simply reject.

Second, you may want to prevent a third party from doing a replay attacks against your site (i.e. sniffing an inocent user's traffic and then sending the same calls over). The easy solution is to go over https for this. The SSL layer will prevent somebody from replaying any part of the traffic. This comes at a cost on the server side so you want to make sure that you really cannot take that risk.

Third, you may want to prevent somebody from using your API (that's what AJAX calls are in the end) to implement his own client to your site. For this there is very little you can do. You can always look for the appropriate User-Agent but that's easy to fake and will be probably the first thing somebody trying to use your API will think of. You can always implement some statistics, for example looking at the average AJAX requests per minute on a per user basis and see if some user are way above your average. It's hard to implement and it's only usefull if you are trying to prevent automated clients reacting faster than human can.

Pierre-Luc Simard
+2  A: 

There isn't a way to automatically block "non browser user" requests hitting your server side scripts, but there are ways to identify which scripts have been triggered by your application and which haven't.

This is usually done using something called "crumbs". The basic idea is that the page making the AJAX request should generate (server side) a unique token (which is typically a hash of unix timestamp + salt + secret). This token and timestamp should be passed as parameters to the AJAX request. The AJAX handler script will first check this token (and the validity of the unix timestamp e.g. if it falls within 5 minutes of the token timestamp). If the token checks out, you can then proceed to fulfill this request. Usually, this token generation + checking can be coded up as an Apache module so that it is triggered automatically and is separate from the application logic.

Fraudulent scripts won't be able to generate valid tokens (unless they figure out your algorithm) and so you can safely ignore them.

Keep in mind that storing a token in the session is also another way, but that won't buy any more security than your site's authentication system.

Pras