How to prevent a Php file being called by AJAX to be loaded by itself

Hello,

I am wondering what is the best way to prevent a Php file being called by an AJAX program to be loaded by itself and thus fake data uploaded via such direct loading of the Php file?
To be exact lets say we have a AJAX Code that calls work.php as in here:

xmlhttp=GetXmlHttpObject();

var url="work.php";
url=url+"?vote_id="+vote;
url=url+"&cookie="+cookie_val;

xmlhttp.onreadystatechange=stateChanged;
xmlhttp.open("GET",url,true);
xmlhttp.send(null);

How can we then prevent someone from loading work.php and loading these values manually and thus by pass our system? Keeping in mind that this is a page that allows non-members to enter certain data.

Thanks,
Dean

1 Like

So you want your work.php only accessible from the javascript and not by pasting its URL directly into the browser?

The simplest solution would be to send a custom HTTP header with your ajax call and then in work.php verify that the header has been set properly. However, this will still allow people to bypass your system if they use developer tools that let them send the same headers. So if you need more protection then use PHP sessions:

Make both your php script that renders the page and your work.php script use the same session (BTW, you don’t have to pass cookie values via url like in your example - the browser will send cookies in HTTP headers like for any other requests). Then make your javascript send a token generated by PHP to work.php and check if the token is correct in work.php. The token could be the session ID but better would be a hash of the session ID. Example:

  1. main.php - generates sha1(session_id()) and sends it to your javascript via generated HTML.
  2. javascript - sends request to work.php like in your example but also sends the token (via URL or via a custom header)
  3. work.php - generates sha1(session_id()) and checks if it’s the same as the token received from your ajax call.

This should work well for protecting access by arbitrary people but will not prevent direct access by people actually visiting your site (those who have valid sessions and get to know your ajax’s URL). For that you may add a timestamp generated by PHP and send it along the token and in this way make the URL expire after a period of time - but then remember to hash both the session_id and the timestamp concatenated in a string! Having a time limit may or may not be problematic depending on your situation.

I don’t think a 100% protection can be achieved in this case because an ajax request is just like any other request and can be spoofed by proper developer tools or libraries like CURL and then you have no way of distinguishing them. You can at best use tricks like the above to make life harder for most people.

1 Like

There is absolutely no way to do so.

You have to understand that that for the server all requests are the same and all the files actually are “called by themselves” all the time.

Thus, you cannot prevent someone from loading work.php and loading these values manually by means of telling an AJAX cal from a direct one. You can only protect your data by means of standard techniques like authorization.

2 Likes

You would need to add some type of authorization requirement as a firewall to that action. Than only allow trusted users access to the action based on whether they have been authenticated or have a specified permission and/or role.

1 Like

Well you could set a http only cookie on main and check in work.php if it is set.
Bassicly you cannot check a http only cookie in js.

http://stackoverflow.com/questions/36877/how-do-you-set-up-use-httponly-cookies-in-php

Ok.
So you are saying set a Cookies on the Php page that is calling work.php via Ajax and
then save this Coockie value in a SESSION and have work.php check that this Coockie is set on client side which coockie value is given to it via SESSIONS?

Will this work? That is work.php is supposed to be a server side execution only!

I guess I need to test.

When there is a Will there is a Way :slight_smile:

No you do not use the client side for the cookie.
Bassicly you execute a server-side code before your output.
Then when you ajax call work.php you check if the cookie is set.

Not even this main.php session trick will be foolproof. It doesn’t mean we can’t visit work.php, it only means we’d have to visit main.php first. If I were a malicious user and I were using an HTTP/scraping library, then this whole stunt probably adds only one extra line to my malicious script.

Looking at your ajax request, I’m guessing you want to prevent people from voting multiple times? The first step is authorization, as colshrapnel and oddz both mention. That is, make the user identify themself with a username/password. Then work.php can query the database and check whether that user has already cast a vote.

Not sure what you mean by this!

Well we cannot have them enter username & password since we want non members to be able to Vote.
As for example you can on StarBucks Site, etc.
So we need to put in place the best security system we can to make it next to impossible to trick the system. OTN, I think I agree with you by now that this cannot be “foolproof”. I am just looking for the BEST NEW idea in this regard. I mean you would think that by now in 2015 some solid near “foolproof” ideas were established regarding this rather common case for collecting user data, that is collecting user data from non-members via AJAX call.

Thanks,

Search what http only cookies are and you would know what I mean.
If not I will make a example in a few.

Nothing is ‘established’ because there’s no such method and it simply is not possible. You can try making things a bit more difficult but at best you can count on approximate results. It all comes down to storing a value in the user’s browser (cookie, local storage) when voting and then checking it on next votes. But these values can be cleared. You can also record IP’s - but still not reliable because many people can have the same public IP or, one person can change IP’s easily.

The only reliable way is authorisation - if you can make sure that one person does not create multiple accounts.

The best thing that could make your votes fairly reliable is to not make the subject of the poll too important or too sensationalist for people. If it concerns light subjects then no one will try to trick your system and you’ll have fairly reliable results. But if people feel they must outvote the others by all means for any reason, there will always appear a few technically talented weirdos on a mission to break the system.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.