Background:
I'm developing a website tracker using javascript. Here's how it works:
1) A user visits any domain the tracker script is on "anydomain.com". The script makes a successful ajax call in the background to my master domain "masterdomain.com".
2) When "masterdomain.com" receives a request, the following PSEUDO code is run. It works by checking for an existing session and if one doesnt exist it creates a new one.
The first call appears to be fine because I am able to receive a session ID in a response. However, each successive call to "masterdomain.com" creates a new session. AKA the server doesn't find the "should be" existing session.
Sample PSEUDO Code:
if(session exists)
{
// update timestamp for session
}
else
{
// set a new session for visitor
}
// load template
api(array("accepted"=>session_id),callback);
Some Quick Facts:
1) This does not appear to be a same origin issue (as I am able to communicate with the server fine).
2) I have tried this with cookies/sessions both appear to not be working.
3) I am using codeigniter (sessions are set not to expire on page close). I have also tried using/not using database sessions).
This problem can also be solved if there is another way to uniquely identify a user each time a page loads on a server (not using IP).
Any help would be greatly appreciated as I'm about ready to tear the rest of my hair out of my head!!!! :(
This answer is incomplete in that you'll have to do some additional research, but the easiest way (which is not actually particularly 'easy') to do this is to use Javascript to place a hidden iframe to masterdomain.com, and set up iframe communication (e.g. using postMessage) to retrieve the session from that iframe to your page.
With AJAX calls you can only send/set session cookies if the URL you're calling is on the same domain as your calling script. I think you should create an iframe, call ajax from within and it should work fine. By the way, I have no idea what you are trying to track.
Related
Everything is working fine if all the processing happens on my own site. The session variable get stored and retrieved successfully.
Now I got a third part integration, which is processed via POST data. I have got session_start() called at the first line of each php file.
start_process.php - sets some session variables as follows and calls third party that redirects to response.php
$_SESSION["id"] = $id // Echoing these shows the correct values
$_SESSION["name"]= $name // Echoing these shows the correct values
response.php - This page receives the response from the third party and tries to get the data from session variables
$id = $_SESSION["id"] // This comes out to be blank
$name = $_SESSION["name"] // This comes out to be blank
On my processing page i.e. the response.php, I am trying to retreive back the session values, I don't get the session variables back.
Searching on SO, few post suggest that to check the value of
echo session_id();
which comes to be as different on the first page and the later page coming back to my site. Searching further shows that the value of the following needs to be blank
echo ini_get('session.cookie_domain');
This indeed is blank. Now I am stuck as I see this value as blank, and even though the session is not getting loaded properly.
Can you please suggest what to do next? Any debugging? Any hints to solve this problem?
Update
start_process.php
has a form whose post action is the url to third party site... as
<?php session_start();
$_SESSION["Check"] = "Abc";
echo session_id();
>
<form name="myform" action="http://<ThirdPartyUrl.com>/pathToSomePage.jsp" method="POST">
<!-- some hidden fields with value and some other text fields -->
</form>
respone.php
The third party gives a response in post request again to my response page where I directly test the output of the POST variables and here I am trying to use my session variables
<?php session_start();
echo $_SESSION["Check"];
echo session_id(); // This is different from the one printed in the start_process.php page
?>
I don't think the third party hosting is on the same server, because currently I am on a shared host and the third party definitely has it's own server.
It's hard to know without seeing some more code (how start_process.php is hooking into the third-party code, how the third-party is coming back to response.php). Here are a couple guesses:
Theory 1: third-party code is messing with your session (if hosted on the same server)
Is this third-party integration hosted on your same server? If so, I would suspect that the third-party could be ending/recreating, or otherwise modifying your session.
Theory 2: third-party is redirecting back to your site using a separate domain
Is it possible that you start off at mydomain.com and the third-party redirects back to www.mydomain.com (or something like that)? Even though those two domains look like they should be the same, they are utterly different as far as PHP sessions are concerned, you'll end up with a different session.
I've dealt with a similar problem when working on shopping cart payment gateway integrations. If the response script is ultimately contacted via the browser (i.e. the user is redirected to response.php after they're done on the 3rd party site), the session IDs and cookies will be preserved. If your response script is contacted via a server side request from the 3rd party site, that request is treated as an entirely new session. In that case a lot of integrations allow you to senda "passthrough" variable that will be sent back to your response script along with the rest of the data generated by the 3rd party site. You can use this variable to connect the user's session to the server side request you receive later on (for example you could create a database that relates the two values). Alternatively you could "cheat" the system. If you're passing the response script location along with your request every time, you could build your own passthrough variable into it. So instead of something like
<responseURL>www.mysite.com/response.php</responseURL>
you could send
<responseURL>www.mysite.com/response.php?key=abcd1234</responseURL>
I would recommend setting the key parameter to the session ID directly, so you'd have to build something simple that could translate between the two (like the table I mentioned above).
First of all you need to start a session before to use it. Before assign any value to a session valiable type into your code: session_start(); Do not forget to destroy/unset the session eighter. Hope it will work
Use cookies with some specified expire timings ! it will works well. updated your question with some code so coder can debug it !
Short answer is: find the cookie!
You can loose at domain or directory level. See session_set_cookie_params() specs.
What about the 3rd part. Does response.php requested from the same browser or from another web app, so have it the same cookie? It seems to me that doesn't.
To solve the problem is required to analyze the process steps to determine the place of every execution
If the thirdparty application is calling itselft to the URL of the response and is not a redirection into the client the sessions are not the same.
Example:
Client navigates to start_process.php and a session is created for client
start_process.php calls the thirdParty
Thirdparty app calls response.php and a session for thirdparty is created
Is important to check that the session ID is maintained by the client cookie and validated in the server. The client that starts the process and the thirdparty are diferent "clients" of the app with their own sessions.
Diagram example that shows you are probably doing based on your question.
Probably you can't call the third party directly from the client. On the client call a page on your host that calls the third party and capture the response (for example using curl)
Diagram example:
We have a legacy (php) aplication, accepting file uploads and they are stored at a path depending on the session id. Now we had to provide a very simple API for this webapp, where through an iOS api (iPad) a file upload is performed. We return an url which the customer will open in an embedded webkit window.
Because the sessions from the upload and view actions are different, we thought to grab the session parameter and return it in our response from the file upload. Then the client gets redirected to that url, we set the session id to the previous id and continue to the page the customer can continue the work.
Apparently, nothing I tried works. We use Zend Framework 1, but that shouldn't really matter. I tried:
Setting a Set-Cookie header (this results in a cookie containing two PHPSESSID values)
Use a setcookie("PHPSESSID", $session, 3600) to set the PHPSESSID
Use the Zend http Reponse with a setHeader('Set-Cookie', 'PHPSESSID=....', true)
The last two options just don't do anything, like I didn't set the session at all. How can I solve this? We actually can't touch the legacy code base that much to modify its working and change the way the path resolving works for file uploads.
So, the flow is:
Request to api.myapp.tld -> Response with a string in body -> Open webkit window with this response string as location -> Request is performed -> Response with a Redirect header and a method to set the cookie to something different -> Webkit performs redirect -> Customer gets to a page with same session ID as the first request to api.myapp.tld.
If there is an alternative to set the session id, it would be great.
That's not trivial to debug, but you have some options. I'm not fluent with Zend Framework 1.x, so this is not framework specific (frameworks sometimes add stuff on top), but PHP specific.
In PHP a session is identified by two things:
Name (example: a common default name is PHPSESSID)
ID (that is the random "number")
The Name allows to use multiple sessions at once, while the ID identifies the session in specific.
It sounds a bit you need to use two session IDs in parallel. I suggest you make the script that needs to deal with the legacy session to have another sessions name than your current script.
You can then pass in the legacy/old session id by using the other session name while your current session can remain as is.
I hope this information is helpful. If you have got problems to implement that, please ask.
I ended up by something simpler. The session was related to the path like this /path/to/location/ . $sessionId. When the second session was started, I simply renamed the directory from the old session to the new one. Simple and fast to get this working.
I just finished coding my first jquery ajax call page. It calls a php page every 1 or 2 seconds and returns json data.
The page basically displays posts of the message board the user is viewing. There are multiple message boards and some users should not be able to view certain boards, however the same php page is used for the call. It pics out the message using $id that is sent by the ajax script.
My question is how would I protect the php page from being manipulated and opened directly? The user can easily change the board id by opening the file directly and changing the URL. Not to mention the other ways.
If there is no easy way, then I guess I'd have to duplicate the majority of the main page to check if the user has necessary permissions. That would mean more server load since the page is updated every second.
Ajax calls are treated by server in the same way as normal page requests. All the authentication and authorization mechanisms are called before serving the page. To make sure just log off and try to get stuff from your page using AJAX. It should not work if your page requires you to log into the site.
In ajax script you can use $_SESSION too - you can check if current user has privilages to specified ID - if not - just deny access.
Save the permissions in a session and check if that certain flag is present?
If an AJAX call can open the page, so can the user, you cannot rely on definitive technique to protect a page. Rest you can follow what #TheVillageIdiot has said in his answer.
I am trying to read a cookie which I've set with javascript, jQuery Cookie Plugin specifically, and then after that I'm reading it with PHP to write it into a database.
For some reason the cookie is being created on page load, but doesn't "exist" until the page is refreshed. Which means that I'm pumping blank fields into my database tables.
The only way I can think of doing it is to AJAX out to a script which creates the cookie. Or ajax out to a script which returns the data to me in json.
The use case is that I'm creating a simple analytics class for an internal project, and I'd like to write into the database the users resolution, colour depth and all that jazz, which I'm using screen.width etc to get.
Cookie data are sent to the server (and forwarded to the PHP interpreter) when the client performs the request. Therefore, a cookie set by JavaScript on the client after the page has been requested from the server will not be transmitted until the next request to same server.
What you'll have to do is to perform some kind of request (could be done via AJAX) where a PHP script handles the incoming cookie information and stores it in the DB.
#jensgram is right. These two scenarios can happen:
User requests your page and (s)he hasn't the cookie. You render the response via PHP, but you can't see the cookie at server. Response gets delivered to the browser and on DOMReady (or events like that) you set the cookie. User sends another request (via interaction with your page). Here you have the cookie at server.
User already has the cookie (coming back to your site) and sends a request. You render the response via PHP, but this time, cookie is available in first shot. The rest is the same.
Two suggestions:
To prevent inserting null (or empty) values into your DB, first check to see if cookie exists or not. If not, simply try to set it.
For implementing Analytics, predefined patterns exist. For example, instead of setting a cookie, you can include your script on every page, and on load of each page, you can get the information you need, and send an asynchronous ajax request to your Analytics Collector PHP file. No need for cookie :)
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.