tags:

views:

4249

answers:

13

How do I prevent my users from accessing directly pages meant for ajax calls only?

Passing a key during ajax call seems like a solution, whereas access without the key will not be processed. But it is also easy to fabricate the key, no? Curse of View Source...

p/s: Using Apache as webserver.

EDIT: To answer why, I have jQuery ui-tabs in my index.php, and inside those tabs are forms with scripts, which won't work if they're accessed directly. Why a user would want to do that, I don't know, I just figure I'd be more user friendly by preventing direct access to forms without validation scripts.

+22  A: 

There is no way of guaranteeing that they're accessing it through AJAX. Both direct access and AJAX access come from the client, so it can easily be faked.

Why do you want to do this anyways?

If it's because the PHP code isn't very secure, make the PHP code more secure. (For example, if your AJAX passes the user id to the PHP file, write code in the PHP file to make sure that is the correct user id.)

yjerem
Nothing more can be said. Don't ever, *ever* trust what the client sends you. Since AJAX methods are meant to return stuff to the browser, ensure in the backend that only authorized data can be returned.
Just Some Guy
My only regret is that I have but one vote to give for this answer.
Jacob
My only regret is that I have bone-itis.
scronide
Since he only wants user-friendlyness, the check for the XMLHttpRequest seems like a fine solution, as long as security has nothing to do with it.
Tchalvak
+6  A: 

It sounds like you might be going about things the wrong way. An AJAX call is just like a standard page request, only by convention the response is not intended for display to the user.

It is, however, still a client request, and so you must be happy for the client to be able to see the response. Obfuscating access using a "key" in this way only serves to complicate things.

I'd actually say the "curse" of view source is a small weapon in the fight against security through obscurity.

So what's your reason for wanting to do this?

Draemon
i like the "a small weapon in the fight against security through obscurity." part - mind if i quote it some time? :)
jcinacio
hehe, go for it.
Draemon
+4  A: 

If the browser will call your page, either by normal request or ajax, then someone can call it manually. There really isn't a well defined difference between normal and ajax requests as far as the server-client communication goes.

Common case is to pass a header to the server that says "this request was done by ajax". If you're using Prototype, it automatically sets the http header "X-Requested-With" to "XMLHttpRequest" and also some other headers including the prototype version. (See more at http://www.prototypejs.org/api/ajax/options at "requestHeaders" )

Add: In case you're using another AJAX library you can probably add your own header. This is useful for knowing what type of request it was on the server side, and for avoiding simple cases when an ajax page would be requested in the browser. It does not protect your request from everyone because you can't.

deathy
A: 

Not sure about this, but possibly check for a referrer header? i think if someone manually typed in your url, it wouldn't have a referrer header, while AJAX calls do (at least in the quickly test I just did on my system).

It's a bad way of checking though. Referrer can be blank for a lot of reasons. Are you trying to stop people from using your web service as a public service or something?

After reading your edit comments, if the forms will be loaded via ajax calls, than you could check window.location to see if the url is your ajax form's url. if it is, go to the right page via document.location

Eric Tuttleman
It's very easy to fake the referrer header.
Alex
@AlexRight, which would be one of the reasons included in the "can be blank for a lot of reasons" statement.Ever answer on this page can be faked, because they are all client input methods - data that the client sends to the server. Mark every answer on this page negative.
Eric Tuttleman
+8  A: 

As others have said, Ajax request can be emulated be creating the proper headers. If you want to have a basic check to see if the request is an Ajax request you can use:

 if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
     //Request identified as ajax request
 }

However you should never base your security on this check. It will eliminate direct accesses to the page if that is what you need.

Eran Galperin
I get undefined index: HTTP_X_REQUESTED_WITH.Do you mean I have to do assign that value myself?
SyaZ
What framework are you using for Ajax requets? (I hope you are not using a homebrewed solution...)
Eran Galperin
And, also that parameter will ONLY be available inside the Ajax request. You might want to add an isset() check if you don't want the undefined index error
Eran Galperin
Apparantly you're right. This is exactly what I want, basic security. Even if user forge the HTTP_X_REQUESTED_WITH (how can one do that anyway?), it doesn't matter in my case.
SyaZ
Syaz, this is not basic security. As Eran correctly said - "you should never base your security on this check"It would be VERY easy to forge (I'm sure wget or numerous firefox plugins could do this very simply)You still haven't said why you might want this - what is there to secure?
Draemon
I already edited my first post to state what I want to achieve -- user friendliness. As simple as that. ;)
SyaZ
A: 

This definitely isn't useful for securing something.. but I think this could be of use if you wanted to have say a php page that generated a whole page if the page was not requested by ajax but only generate the part that you needed returned when ajax was used.. This would allow you to make your site non ajax friendly so if say they click on a link and it's supposed to load a box of comments but they don't have ajax it still sends them to the page that is then generated as a whole page displaying the comments.

A: 

Cookies can be faked as well

AlBeebe
A: 

COOKIES are not secure... try the $_SESSION. That's pretty much one of the few things that you can actually rely on cross-page that can't be spoofed. Because, of course, it essentially never leaves your control.

Tchalvak
A: 

AlBeebe & Tchalvak, read the article before making assumptions. It's secure.

Simon
A: 

I may say, what an hack of potatoes. What is safe to do now?

Have you gentleman saddle it up? I need ammo to pull the trigger here.

Thanks.

Brian core
A: 

Hi

I'm not a programmer. I've found a free Ajax contact form - http://www.solucija.com/free-and-simple-ajax-contact-form - and was wondering if I can add this code to prevent email harvesters from accessing the sendContact.php page?

Thanks

Pete
A: 

Pass your direct requests through index.php and your ajax requests through ajax.php and then dont let the user browse to any other source file directly - make sure that index.php and ajax.php have the appropriate logic to include the code they need.

Antony Carthy