i've a jquery script which post/get data to .php script. but i wanna prevent direct access to the php script. for example if the user look at the html source code,they will be able to access the php script directly by copying the url from the js file and i dont want that. how do i prevent users from doing that?? i want the user to use it via the html UI. i've google but found no link on this. however, i did notice that some popular websites are able to do that. how should i go about doing this??
It seems like a simple redirect is what you're looking for here.
Add something like this to the top of your php file. This will prevent the page from being accessed if the proper post has not been made. Of course you'll have to change the post and redirect to content more relevant to your project.
if (!isset($_POST['data'])) {
header('Location: your-redirect-location');
}
You may also be able to redirect based on the $_SERVER['HTTP_REFERER'] variable.
EDIT: I was going to explain this in a comment but it's too long. I should note that this is a simple solution. It will keep people from accidentally accessing your script. It's really difficult to create a 100% secure solution for your issue, and if somebody really wants to access it, they will be able to. If you don't have anything secure in the script in question, this will be fine. Otherwise, you'll have to look for an alternative.
Here is one solution:
<?php
if(isset($_POST["post_var]))
{
//to the code you want to do when the post is made
}
else
{
//do what you want to do when the user views the post page
}
?>
how do i prevent users from doing that?
You can't - all you can do is mitigate the risk people can fiddle with your script. Making sure you have the right HTTP_REFERER and/or POST data are both useful in that regard: a "malicious" user would need more than pointing her browser to the URL.
More techniques can be used here:
using session variables: you might not want users that are not logged in - if applicable - to use the URL.
using a one-time challenge (token): you can place a value in the HTML page and have the JS code send this value along with the POST request. You store this value in the session when it is generated. Checking the POSTed token against the session token guarantees the user has at least "seen" the HTML page before submitting data - this can also be useful to prevent duplicate submissions.
However, remember that anything a browser can do, people can do it as well. All these techniques can prevent the curious from doing harm, but not the malicious.
All you can do is making sure nobody can really harm you, and in this regard, your Ajax URL is no different than any other URL of your site: if it's publicly reachable, it has to be secured using whatever technique you already use elsewhere - sessions, user rights, etc.
After all, why should you care that users use this URL not using a browser ? You might want to think of it in terms of an API call that, incidentally, your page happens to use.
Your problem is similar to and has the same problems as a cross site request forgery.
To reduce your risk, you can check the request method, check the referrer, and check the origin if set. The best way is to have a secret token that was generated on the server that the client transmits back in every request. Since you're dealing with friendly users who have access to your live code, they may be able to debug the script and find the value, but it would only be for one session and would be a real hassle.
Related
I'm making a register page, signup.php, and basically what I want it to do is check for errors and if there are none, redirect to register.php. That is fine and whatnot, but register.php is the page where the actual account is made (e.g. mySQL query). Of course, in order to do that, I actually need the params gathered form signup.php. I was wondering if I could do something like this..
header("Location: register.php, TYPE: POST, PARAMS: {user,pass,email}")
Obviously I can not use $_GET as I am transmitting sensitive data (e.g. passwords).
Any ideas/suggestions?
EDIT: Thank you all for your answers. I am now storing the parameters in a $_SESSION variable.
I see no point in such redirect.
Why not to post right away to register.php?
And then check for errors and save data in database in the same register.php?
without any redirects
No, you can't, and such data would be just as insecure to any determined attacker.
Store the data in a session variable for use in the next page.
Even if this is possible, you will hit another brick wall - the implementation of redirects in the popular browsers. While the standard requires, that it asks the user if a post is redirected, all popular browsers simply interpret the redirect as a GET. In short: you can't redirect a POST that way, you'll have to find another way without a round trip to the client, or use GET.
Also, you should be aware that unless your requests are done via https, both GET and POST will present the sensitive information to any listener, as POST simply buts the query string into the http request and not the url. Security wise, both are the same.
You could store them in the $_SESSION and refer to those in the register.php page, doing some checking to make sure someone has actually filled out the information and didn't just navigate to it.
If I have an app and it is run inside facebook. the first load I will get the
$_REQUEST['signed_request']
but if you click on any link inside my app and navigate within the app you will lose that $_REQUEST['signed_request'].
Is there any other way to know if my app is being run in a browser or inside facebook?
You can save value of signed_request in php session, something like this:
session_start();
if (isset($_REQUEST['signed_request'])){
$_SESSION['signed_request'] = $_REQUEST['signed_request'];
}
Later you can check if signed_request value is saved in session:
if (isset($_SESSION['signed_request'])){
//do something
}
You can continue to pass the signed_request around. Within your app, all your links should end with ?signed_request=<whatever> (or &signed_request=<whatever> if there is already a query string), and all your POST forms should include signed_request as a hidden input. Then you will always have access to signed_request.
If you really only need to know whether your app is being accessed through Facebook, the simplest way is to use a unique url in your app settings -- either a unique hostname like fb.yoursite.com, or a unique directory name like www.yoursite.com/fbapp/ . Then you configure your server so the unique hostname/directory points the same place as the regular hostname/directory. That way the same files can be reached either way, but your scripts can check the $_SERVER info to tell whether it's a Facebook request.
HOWEVER...unless you are strictly dealing with non-authorized access, you have to consider whether that will really solve anything. If you have to "detect" things like this, you must not be carrying any persistent state info, and your user will lose his "identity" as soon as he goes to page 2. So most likely, what you need to be considering is not a way to tell on each page whether the user is in Facebook, but rather a way to parse all the info you need on the first page and then make that available in all other pages. Many people use PHP sessions for this. Personally I think that's a bad idea, and would do something more like what Ben suggested in his answer (using GET and POST to pass the info you need).
Personally, a very simple yet effective solution I've used is some client side javascript (which can obviously be disabled etc) - this works nicely for a simple redirect and it won't work in every case.
// Redirect if the page is not an iframe
if (window.location == window.parent.location){
window.top.location = '{{ facebook_tab_url }}';
};
What are some methods that could be used to secure a login page from being able to be logged into by a remote PHP script using CURL? Checking referrer and user agent won't work since those can be set with CURL. The ideal solution would be to solve this without using a CAPTCHA, that is the point of this question to try and figure out if this is possible.
One approach is to include some JavaScript in your login form, and make it so that the form cannot possibly be successfully submitted unless that JavaScript has run. This makes your login form only usable for people with JavaScript turned on, which CURL doesn't have. If the necessary JavaScript is some kind of challenge/response that differs every time (for instance use something like http://www.ohdave.com/rsa/ to make it non-trivial), the presence of the correctly set value in the form is good evidence that JavaScript ran.
You won't be able to stop all automated scripts though, it is easy enough to write scripts that drive an actual browser engine, and they will pass this test.
There isn't any way to prevent it simply. If the script knows the user name and password they will be able to login.
You could use a captcha so that automated logins won't be able to read it, but that will be a burden on actual users as well.
If you are concerned about it being used to try and brute force a login, then you could require some additional information after several attempts.
Disable the account and require reactivation via email
Require a captcha after several unsuccessful attempts
if I undestand correctly :
you have login page what execute login script
login script is hacked by remote cURL script...
Solution
in login page place hidden element with secret unique code what can happend only once, save this secret code in session, in loging script look in session for this code, compare with what was posted to the script, should same to proceed, clear session...
more about subject: http://en.wikipedia.org/wiki/Cross-site_request_forgery
cURL is no different from any other client (e.g. a browser). You could use nonce tied to a session in a hidden input field to prevent POST requests from being made directly but there are still ways around that. It's also a good idea to limit the number of log in attempts per minute to make brute-force attacks more difficult if that's what you're worried about.
iam using ajax for sending requests to one of my php pages in the site... but i do this from my html page. This is secure....
But what if others know my php page and they send ajax requests to that page from their script? This may cause any security problems.
How can i avoid this ?
You seem to be trying to defend against CSRF attacks.
You can include a nonce in your page, then require that all AJAX requests have that nonce.
Since the attacker is on a different domain, he will have no way of getting the nonce.
The only way they can send AJAX requests to your page is if they are on the same domain (ie. their script would have to be hosted on your domain).
AJAX won't work cross-domain, so it's quite secure.
There is very little you can do to stop this, the only think that can help prevent this is by having a good application architecture.
For example, the following rules will help:
Try and keep your Ajax down to read only.
If you have to use Ajax to write then you should follow these rules
Only allow users that are logged in to submit data
Validate Validate & Validate your post data, Make sure its exactly as you expect it
Implement a form hashing technique that generates a unique hash for every form on every page, and validate against a variable within the session Aka (Nonce)
If the user is logged in make sure there's a validation period, such as "You must wait 30 seconds before posting".
Always use session_regenerate_id() before you call session_start
These are just a few pointers that should get you on your way, when researching these you will come across other techniques used by other site owners but you should always remember the following 2 rules.
Never trust your users, just act like you do
Whitelist and never blacklist.
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.
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.)
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.
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?
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.
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.
thanks, albeit I use
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
if(IS_AJAX) {
//Request identified as ajax request
}
cheers!
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
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.
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.
In the javascript file that calls the script:
var url = "http://website.com/ajax.php?say=hello+world";
xmlHttp.open("GET", url, true);
xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
then in the php file ajax.php:
if($_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest") {
header("Location: http://website.com");
die();
}
Geeks can still call the ajax.php script by forging the header but the rest of my script requires sessions so execution ends when no valid session is detected. I needed this to work in order to redirect people with expired hybridauth sessions to the main site in order to login again because they ended up being redirected to the ajax script.