I have a file, caller.php, which takes a GET URI that specifies a value to search the database for. The data is then returned in JSON format using php.
I want to protect caller.php so that it is only accessible from another page, get.php, using an AJAX call.
What is the best way to go about this?
I want to protect caller.php so that it is only accessible from another page, get.php, using an AJAX call.
You can't. An AJAX call can be easily faked, as can its origin.
There is no reliable way for you on server side to tell whether a call is an Ajax one or not, nor where it came from.
You need to secure your Ajax resource the same way you would secure a normal page - e.g. through an authorization system like a user login, etcetera.
Without such an authorization system in place, you have to assume that everyone can access the URL.
You could check the session to see if the call is authorized or not. AJAX requests will send you the PHP session cookie. This assumes that caller.php is secured by some kind of user login system that uses sessions
Related
I wrote a API for a system. It is a PHP file, which is called with some parameters. It is called like this: "https://abcdefg.de/api/api.php?test=test". This script returns sensitive data when it is called. To make sure only the right api users get the information the parameters has to contain correct credentials.
To make the api more secure the idea was to check in addition who is calling the script. For example only the website "https://test.de" should be able to call the api script. But how to achieve this in PHP? How to check what is the url of the "caller"?
I already tried $_SERVER['HTTP_REFERER']; but I read that it can be easily manipulated and in our case it returns always null, because we use https instead of http.
Is there a solution to our problem?
Thanks in advance,
Filip.
HTTP_REFERER will not be working in real with API, it's related to the form submitted from another page or website, in case this is the situation this is called cross-site request forgery, the solution here is to create a token in every rendered form and send it with the submitted data, from the backend, you will validate this token (most of the time is saved in the sessions), you can check it
So I have a JavaScript and php web app. In my app I have times where JavaScript will call a POST request that creates a post for example. I want to know what is the best way to authenticate my request to prevent anybody from just going to that URL. It doesn't need to be that flexible. I'm not going to have multiple apps. I just need a one case solution in php and JavaScript.
EDIT: second question. Is just making sure the URL the request is coming from enough?
You can't.
You can do things like adding an extra header to the request when it comes from your JavaScript, but since you have to send the instructions on how to do that to the browser, anyone can read them and duplicate them for their custom built non-JS request.
On the WWW you can authenticate people (with credentials), but you can't authenticate clients (unless you supply the client software in a compiled bundle … and even that isn't reliable, the official Twitter client auth keys are out in the wild now).
Is just making sure the URL the request is coming from enough?
If you mean "checking the referer header", then no. That is set by the client, and the client can set it to whatever they like.
Best thing would probably be to establish a PHP session and send an identification stored in $_SESSION to the javascript. In every AJAX POST you add this identification and check it serverside to what is stored in $_SESSION. If they do not match it's either someone trying to manipulate the URL or a CSRF.
If you want to prevent the original client from doing multiple requests within a session you will need to send a nounce-number from the server to the client which will be usuable only once. See:
http://en.wikipedia.org/wiki/Cryptographic_nonce
You can place this line on top of your script
<?php if ( ! defined('BASEPATH')) exit('Permission denied: direct access');
as the first line of your php file you are sending the POST to.
EDIT -> Or something like
if(!isset($_POST))
{
die('no direct access allowed');
}
else
{
//all your PHP code
}
you could also include your own variable in the post and use it in
isset($_POST['your variable'])
to check.
I use
$.post('ajax/test.php', function(data) {
$('.result').html(data);});
to send data and retrieve information and show it to the user. But "hackers" can access my file (test.php) just typing it in URL. Is it possible to detect if the call is made from jQuery or not?
Is it possible to detect if the call is made from jQuery or not?
Yes, but the same "hackers" can as easily fake a jQuery call. There is no reliable way to detect whether a call was made from jQuery, or using other means. Anybody can make a request to a resource.
If you have sensitive data on the web, you need to protect it using classical means like a user login, HTTP basic auth, or IP limitations - just like a normal web page.
Check the referrer on the server side. If not from your host, reject.
I'm making a PHP app to allow our customers to retrieve information from our database, using pre-defined functions. Perhaps PHP isn't the best choice for this, but the same page is also used as a backend for a flash app, and we don't have the time to rewrite it in another language (still, if we did have that time, I'm open to suggestions).
They will access the page via a URL, something like:
http://myurl.com/test.php?function=getUser&username=John
This will call the function getUser($username) and pass the value John as the $username parameter. Here's the twist: this page will be called from an application that the customer creates, not from a browser.
They are allowed to get info about some users, but not others. To enforce this, I require them to provide login information. I'm not sure how I can keep that user logged in so that they don't have to pass their login information every time they call a function, which can be multiple times per second.
I don't think I can use sessions or cookies, since they are not calling the page from a browser. So how can I keep that user logged in?
You can look into setting up something like a SOAP API on your end. Then, you can provide them with a token that goes back and forth (and possibly changes) between each request they make.
Have a read over SOAP and see if it gives you any inspiration at the very least. As far as implementing it, your options are many. Maybe consider using a framework?
You've hit the stateless wall :D .
You will either need to create a session aware browser client object with some library or some token exchange. But as long as you are using a separate session between calls you will need to hit the database again to authorize the user; token or not.
Simple answer: You can't, since HTTP is stateless.
But: You can use the same principle as cookies do, which is "send some authentification info along with the request without transmitting the secret". Have a look into OAuth and if it fits into your scenario. You can even use ready-made libraries for PHP.
From a security standpoint, can someone give me a step-by-step (but very simple) path to securing an ajax call when logged in to PHP?
Example:
on the php page, there is a session id given to the logged in user.
the session id is placed dynamically into the javascript before pushing the page to the client.
the client clicks a "submit" button which sends the data (including the session id) back to the php processing page.
the php processing page confirms the session id, performs the task, and sends back data
I'm stuck on how (and whether) the session data should be secured before sending it through an ajax request. I'm not building a bank here, but i'm concerned about so many ajax calls going to "open-ended" php pages that can just accept requests from anywhere (given that sources can be spoofed).
PHP can get the session data without you having to send a session ID via javascript. Just use the $_SESSION variable. If you want to check if a session exists you can just do
if(isset($_SESSION['some_val'))
//do work son.
You'll need to use JavaScript to asynchronously pass user input back to the server, but not to keep track of a session.
Don't send your session data with javascript.
You don't need to (in most cases).
Just post the data with javascript and let PHP retrieve the session data from... the session.
Depends on how you setup your session data.
One simple example would be you have a session called username.
When PHP gets the request from javascript you can do: $_SESSION['username'] to retrieve the sessiondata.
This is a very simple example just to show how it can be done.
As noted above, you don't need to send any session identifiers out with your javascript, to the server an AJAX request is the same as any other request and it will know your session just fine. So basically, just don't worry about it, it's already taken care of.
It's another part of your question that worries me.
i'm concerned about so many ajax calls going to "open-ended" php pages that can just accept requests from anywhere
It worries me too; you shouldn't have any "open-ended" PHP pages hanging around at all. Every public .php script should have authentication and authorisation done. The easiest and most maintainable way to achieve this, IMHO, is to have a single controller script (e.g. index.php) that does authentication and authorisation then sends the request to an appropriate controller. Aside from this controller, all other scripts should be outside the document root so that they cannot be called directly.
This means that you only ever have to worry about authentication and authorisation in one place; if you need to change it, it only changes in one place. It means you don't need to worry about accidentally leaving some executable stuff in some library PHP file that's not meant to be called directly. It means you don't need to shag around with mod_rewrite rules trying to protect .php files that shouldn't be in the doc root at all.