PHP session_set_save_handler: read() before write() - php

I'm trying to save all my session data in the Database and have this class that should handle all that and have used session_set_save_handler to set that up. Now, I don't know if it's because I don't fully understand the whole idea behind that function but the problem I'm running into is that the read() function of my Session handler class is called BEFORE the write() function is. And the reason why that is not good is because read() is trying to look for information in the database that has yet to be written into the database and of course it gets empty results.
So I decided to read the documentation behind session_set_save_handler and it looks like the only time write() is called is when the session is terminated or when PHP is closed. From my perspective this seems pretty useless... why would anyone write() or store this information at the END before they could ever get a chance to retrieve it?
What I'm trying to do is when someone creates a use session, this information is written into the database and whenever I want to check for authentication or lookup user values I want to retrieve said information.
Am I going about this all wrong?? I appreciate any clarification. If anyone needs any code to demonstrate what I'm trying to do I'll update this.

From my perspective this seems pretty useless... why would anyone write() or store this information at the END before they could ever get a chance to retrieve it?
What do you mean before they got a chance to retrieve it?
To retrieve it, the read method is called – and it is called before, so that you already have the info. But somehow this is what you are complaining about …?
Am I right in assuming that you don’t have much understanding of how PHP’s session mechanism works at all?
You call session_start on top of every script. If PHP finds a session id in the parameters passed to the script, it looks for an existing session with that id, and if it finds one, it reads the data from it. From that point on, you can work with that data – PHP has put it into the super-global array $_SESSION for you. You can access it from there, and you can put new data into it or alter the existing data.
And then, when the script ends, or session_write_close is called, the data is written back.
So of course the read function is called before the write function.

Related

Is it possible to pass in the session as a variable like in Python for PHP?

So I've been working on porting a python tester to PHP, but I'm fairly new to PHP still. I understand there is a session command within PHP, and I've read the documentation as well as other questions that have come up here in stackoverflow that are close to it, but not quite what I'm looking for.
So my question is whether if there is something similar to sess = requests.Session() from python to PHP, i.e. is there something I could pass in just like I did in python that can occur also in PHP?
EDIT: So I've re-read the documentations for both the python Request package and Sessions for PHP. And I think the meat of my question is if there is a way to have a session object in PHP that holds persistent parameters across POST and GET Request? And to further explain, my main problem is that I have certain POST and GET endpoints that require a login, but even after using the login POST first, I still receive a 401 error code after.
Example Code:
$current->httpPost($accountLoginURL, $accountLoginPostData);
$current->httpPost($followFriend, $followFriendData);
And even after the first line gives me a 200. The second gives me a 401.
You can assign to and read anything you want from the $_SESSION array. It's just a regular array like any other in PHP, except for two things:
a) It's a superglobal
b) IF you've called session_start(), then PHP will auto-populate the array from whatever's in session storage (files, db, etc...), and auto-save the contents of the array upon script exit or calling session_write_close().

How safe is a PHP function from being called by exploitative means?

Background
I use .htaccess to redirect every URI to a single PHP file that displays the right page by calling different functions with different inputs based on the requested URI. I found myself checking user input twice. Once in the handling PHP file that checks first if everything is fine before calling the display function and than again within the display function, to make sure nobody exploits the function by calling it with wrong parameters (e.g. with the username of someone else). This means, that I need twice as many mysql querys etc. for checking valid inputs.
I can't just check within a function because based on those checks, the handling PHP file calls different functions. So I have to perform the checks at least there. But the more I think about it, the more I wonder, if it is necessary to check again within a function. I started this because I was worried that somebody might call one of my functions with improper input, but I guess if somebody can call one of my PHP functions and pass wrong parameters, I'm pretty much screwed already right? Because as far as I understand PHP, this would mean that this person already has access to my server at least via a shell or something like that.
I should further add, that I never ever call a function via a variable like discussed in this thread: Call PHP function from URL
Question
Is it a security risk, not to check the parameters passed to a function within that function, if you already checked it before the function call?
Good rule of thumb - Pretend EVERYONE is out to pwn your app! (Yes get out your tin foil hat!). Good practice would be to clean the data for example putting data in a database, you should still clean it coming back out of the database.
Unless you are in a position where one of your functions is providing the parameters and there is no way to access the (potentially insecure) function except through the preparation function then I would advise cleaning all data
HTHs - Thanks,
//P
Check out Private Public and Protected Functions

Can I connect() without session_start()?

I have found no clear explanation if it is possible to allow someone to visit a page that requires a connection to a database without any need for a session to start.
I cleared the session_start etc from some pages and the pages died
EXAMPLE CASE
If I click on a url that has been created with $_GET...
www.site.xxx/cat.php/?cat=hitlermoustachefunnyhaha
will that page require a session_start etc to be able to fetch data from the database?
POSTSCRIPT
Error indeed found to be Human. As suggested by answerers if you simply convert a page written with one logic sequence it means all code logic had to be refollowed and ALL validation processes need to be skipped. DOH!
Strange question. answer is: depends on your code.
you need session_start() to start the session, and be able to get information from the session. If you do not use information from the session, you'll be able to do what you want.
So while technically the answer is "no", the session was there for a reason, and together with "the pages died" the answer is probably yes.
It looks like you do not know your codebase that well, so you need to look around. Go look for LOC with $_SESSION in them. IF they are used for building queries or stuff, then you obviously need the session.
No, you don't need sessions to use a database connection. Those are completely independent.
Nope. You do not need a session in order to fetch data from a database. But, the PHP code can also check for a session and die if it doesn't find one. Do you have any code to give? If so, I could better answer your question and possibly give you a reason why the page dies.

PHP Session State Not Saved

I am working on a Web chat application. I recently ran into a problem where a particular session variable is not being saved. I have no clue why this is happening as everything else appears to work fine. Code:
This is the class that invokes the function the command is associated with. It is called like this: Command::process("whois", "username_goes_here");
What could be the possible problem and how do I fix it?
In case you need to save Objects in a session, please note, that the object's class needs to be loaded before the saved Objects get back to life from the session.
In this case, load the object's class definition first, then read the object from a session.
PS: Hopefully, the value of $command doesn't get passed directly from the HTTP request into the function...

PHP Session not written after Output(echo or print_r on external ajax Call)

I´m having some serious trouble debugging this particular problem and I hope someone has a clue what i´m doing wrong.
I have a Custom CMS system working that uses Paragraphs as building blocks that get updated using Ajax(prototypejs) calls and functions that parse the HTML chunks in given order, clean them up and save this data in associative arrays in a Session variable.
Users log in, Session is created and I can check for this session without problem in every page I need it. The system works directly on the definitive websites, so the user can see his updates on realtime and browse the site as a normal user would do, but editing.
So, nothing new here. But here is the weird thing.
Enduser site on edit mode(admin user logged in): path "/"
After the logged status is verified, a function processes the editable content and saves an associative array to session, it also starts some javascript objects for editing every paragraph. Data is actually saved, I can use an external script to check if it´s there after this php script ends.If I load a new page(new content), Session gets updated with new data)
Admin User modifies a paragraph using an Inplaceeditor and this HTML chunk is send via Ajax to a php script that starts the named session, reads the present session data, checks if a paragraph should be modified, appended or deleted and reassigns values to existing array keys in $_SESSION. if i make a var_dump() o print_r to $_SESSION after assigning new data is there.After that the script echoes the processed html, and ajax updates the original paragraph on the calling page.
This script is in /admin/cms/...etc, that means at least 4 directories inside the root of the site.
When the script ends, I check using the same session dump script to see if data was really written/commited, but no, $_SESSION has only the original data from the calling page.
Same ID, same session name, same session_start() but no data gets written.
This whole operation is very quick, so I though it could be a speed problem, scripts ends before session_write_close can make his work.
But if I add a new key to $_SESSION array and put some data there, data gets updated and written. If i don´t output anything on this script and just process data and set session variables it also get´s updated and written.
It´s like some members of $_SESSION array are getting blocked to update.
What i did to track this error and what i´m sure i´m not doing wrong.
1.- register_globals are off of course
2.- session_name() and session_start() are always present and in the given
order. I used to have multiple
session_start() -close on a same page
to use several named sessions, but to
refine the problem this is not longer
so.
3.- I use session_write_close() after session data is processed. Also
tried without, letting php decide
when to commit data, but no luck.
4.- I`m using only cookies for SID.
5.- sessions are stored on /tmp, i can see the data getting updated.
I also tried using a custom save
handler on DB, but same problem,
"_write" got only called when no output as present.
I searched php.net, stackoverflow, google, etc for this subject. I never ask without investigation, this is my first time in many years...but it´s just so unlogical it must be something tiny a haven´t thought of.
The most weird thing is that when I just process data without output $_SESSION gets updated ok. But if i modify this script afterwards by adding the output and try again, instead of just having the new(last) value present I get the original value back, the one created by the calling page at first place, sometimes after playing around a few times! PHP can´t cache values between scripts or?I dont have globlals on.
I´m really clueless. This system worked flawless on PHP4.3, since i´m using 5.3.3 for two moths my users where caliming data where getting mixed up, so i checked and yes, there are serious problems. Today I updated to (5.3.6) and I can´t get this session values commited.
Script code called via Ajax:
<?
session_cache_limiter('nocache');
session_name("CMS_ses");
session_start();
include('../htmLawed/htmLawed.php');
include("utils_cms.php");
include("../../../php/utils_array.php");
$value=$_POST['value'];
$editorId=$_POST['editorId'];
$clase=$_POST['clase'];
$editorId=str_replace("pre","",$editorId);
$value=html_entity_decode(stripslashes($value),ENT_QUOTES);
if (strlen(trim($value))==0)
{
die();
}
$value="<div id=\"$editorId\" class=\"$clase\">$value</div>";
$newXHTML=$value;
$retorno=CMS_nuevoBloque($newXHTML,$editorId);
$_SESSION['data']['CMSeditores']=$retorno[1];
$_SESSION['data']['CMScont']=$retorno[2];
session_write_close();
print_r($retorno[0]); //Offending part...without everything works
?>
really nothing strange here....main page code is even simpler, no strange php directives, etc.
Here is the header of the caller page
include 'php/db.php';
$len=$_GET['len'];
$sec=$_GET['sec'];
$cont=$_GET['cont'];
$admfin=$_GET['admfin'];
$fecha=$_GET['fecha'];
$token=$_GET['token'];
$cur=$_GET['cur'];
$PHP_SELF=$_SERVER['PHP_SELF'];
session_cache_limiter('nocache');
session_name("CMS_ses");
session_start();
$passvar='';
unset($adm);
if ((!empty($_SESSION['cms_logged'])) and (!isset($admfin)) )
{
$nivelpermisos=$_SESSION['cms_logged_group'];
$useractual=$_SESSION['cms_logged'];
$adm=1;
}
elseif (empty($_SESSION['cms_logged']))
{
unset($useractual);
}
//.........rest of the code
UPDATE: I did late night tests and found someting i don´t understand.HElP please:
It has not only to do with Sessions but also with Mysql Querys. Same code, but instead of trying to write to $_SESSION array i made a simple update to a Innodb table using the session_id. When i Output some code, the update does get executed,(i can output the query string and no mysql_error() or notice) problems, but checking the database the row doesn´t get updated. Letting the output out if the script and Query does get commited. Only common thing is sessions are started and output is made.
I restarted Apache, etc(who knows) but no luck. Then i made something really stupid, because this is a server side thing. I changed my browser to Firefox(using safari) and everything works! Ok, recheck, back to safari, nothing works. Both running side by side, same issue. PHP is server side, how can different browsers handle code different, can a browser say to apache rollback, request not handled or call the same script twice without notice(checked safaris developer console and the script is called only once) ? Can safari resubmit data silently because it "thinks" ajax failed? I checked headers using firebug and Safaris developer tools , nothing strange but whenever i make a Ajax call with safari, the caller page reloads data(Aka conection to server...).
I really don´t understand nothing.
I had a similar problem to this (if I have understood correctly). I needed to force session data to be written (for a custom session driver) after scripts have finished running. A shutdown function can be registered which should run after scripts have finished.
Maybe this will solve (or help you to solve) your problem.
http://php.net/manual/en/function.register-shutdown-function.php
Thank's for your help. I was doing everything in the right order and still session data was not being written. Session names where necesary because sometimes we test many sites on the same domain using the same custom CMS. So, finally, after making lots of test and no luck, i found that register globals was active on this server(we never use it, code was written having this option off in mind of course), but it messes with sessions!. Switching this off made a huge change. No more problemas. I also made a custom session handler in DB, so i could track the problems in an more centralized way.
Conclussion: Never use register globals + named sessions, an complex data in sessions.
Anyway, i will give this issue more time and more tests. Ajax calls are also sometimes too fast, i had to put a sleep command so writing the session data was really done.Thanks
I am not sure but few suggestion i think may be helpful.
delete session cookies before refreshing the page for testing purposes :)
Ensure that you're not assigning any arrays with a key containing the pipe character (|). This will prevent the session data from being serialized and saved.
Do session_regenerate_id(true); many cases session_write_close doesn't seem to matter with out session_regenerate_id. or just do session_start() after session_write_close() if you are relying on SID ; and in your case i think this is what is causing problem to you as you are ending the current session every time and not re starting it for the next page. hope u get my point. Further more To Make sure data is actually flushed out to the browser use ob_end_flush();
i could not understand the connection between
$_SESSION['data']['CMSeditores']=$retorno[1];
$_SESSION['data']['CMScont']=$retorno[2];
and
$nivelpermisos=$_SESSION['cms_logged_group'];
$useractual=$_SESSION['cms_logged'];
i think you need to paste some more code where the data part is causing problem instead of admin login part.
i hope this helps you.:)
Is there any reason you're establishing the session name twice? I've had issues in the past where I would establish the session without a name, then another piece of script (not mine) was naming the session. Even at the end of the script I was able to print out the session variable, but once I went to a new page my session had been forgotten. It wasn't until I copied the name included in the 2nd script into my session call that it was solved.
Check that there's no other session names being used; also, maybe try only naming the session once, at the first call to the session?
Question: Are you calling session_start() first thing... before ANY output to the browser and before any variables are assigned?
Sounds silly but give it a try.
Also, why are you using session names? Really not necessary unless you have a lot of session variables with the same name serving different purposes and if thats the case then you need to fix that first!
I had a similar problem but it was having with ie few years back. IE manipulates the header on its own way and that causes strange php bugs that you can find in php.net archives.
#Diego Pino Navarro, please see this help page and find Safari and it's issues with php.
I also found "Safari "forget" http-authentication's logon-information".

Categories