Jump to content

Failed to write session data (user) ...


vm101

Recommended Posts

Hello PHP Freaks

 

I'm new to PHP and I need to bring a website back to life. I'm struggling and could use some help. Thank you in advance!

 

The website was written a few years back and my job is to set up a new server and update the website. On my personal computer, say computer A, I have the old website basically running. On computer B, the server for the new website, I'm struggling to get things working. I did not write the old website and I know very little about website development.

 

login.php: This webpage asks the user for login info and then checks the username and password against the mysql database. If correct, it saves the login id to $_SESSION. "$_SESSION['loginID'] = <userID>". I check if "isset($_SESSION['loginID'])" and it is correctly set provided I give the correct username and password.

 

index.php: This webpage has some basic text. Eventually it checks to see if the user has logged in via $_SESSION['loginID']. If the user is logged in, then it opens up more links and features. Even if in login.php I logged in sucessfully and $_SESSION['loginID'] is set, in index.php $_SESSION['loginID'] is not set.

 

When I run "php -f login.php", here is the error: "PHP Warning:  Unknown: Failed to write session data (user). Please verify that the current setting of session.save_path is correct (/var/lib/php/sessions) in Unknown on line 0"

 

I figured this was a permissions error. I have /var/lib/php/sessions/ 777 and all of the .php files for the website 777. Didn't work. In /etc/php/7.0/apache2/php.ini, I changed the session.save_path to "/tmp/". Didn't work. Before session_start(), I made a directory with 777 permissions called sessions and set "session_save_path("/var/www/html/sessions/". Didn't work. While on the other hand on computer A, the old code works fine even if /var/lib/php/sessions/ is owned by root.

 

Any ideas what might be wrong?

 

A few things you should know, there is a file called session.php which has a "class websession".

Before session_start(), "$session_class = new websession()" and session_set_save_handler is used to replace _open, _close, _read, _write, _destroy, _gc. 

 

I've included some of the files here. I deleted some stuff but the general idea is there.

 

Thank you for any help

 

vm101

authorizePHPFreak.php

headerPHPFreak.php

indexPHPFreak.php

loginPHPFreak.php

sessionPHPFreak.php

Link to comment
Share on other sites

As you can clearly see in the session class, this application doesn't use file-based session at all. It implements a wonky MySQL session handler, and now something went wrong. What went wrong is impossible to tell from here, because the class does everything to hide this information.

 

But this is by far the smallest problem. The entire code is riddled with security vulnerabilities, defects and plain nonsense. Putting this online is irresponsible and will put your users, your server and everybody within reach at great risk.

 

This is not a joke. Even if you think that the website itself is irrelevant, you will be in trouble as soon as the server gets compromised and spreads malware or attacks websites.

Link to comment
Share on other sites

Thank you for responding. 

 

Does the websession class replace whatever default php has? I just figured it was an add on.

 

So the bigger problem then. The things I plan on doing is changing the md5 hash to something else since that is out of date. I've also read that I need to sanitize all of the inputs; I'll be working on figuring that out. There are definitely defects since I deleted most of the lines. I'm sure the files don't run right now these were just meant to show the general idea. What are some of the other security vulnerabilities and nonsense that I need to fix/update?

Link to comment
Share on other sites

In general, in order for a mysql session system to work, there has to be at least one table in the mysql server that the session data is being written into. If the database and table doesn't exist, or the system doesn't have a mysql user/pw combination that can connect, then your system will be non-functional.

In other words, the credentials/configuration are required to make this work.

 

Changing all database calls to use mysqli or PDO, along with parameter binding, is the first and most important step towards improving security in regards to SQL injection exploits. It also eliminates the very complicated and often confusing issues related to input escaping.

 

 

In general, most people here are not going to spend time downloading and looking at a bunch of source files.

 

It's really up to you to create specific questions with pertinent code segments as best you can determine.

Link to comment
Share on other sites

I would start from scratch. Trying to repair the code you currently have will likely take more time than writing a new implemention in modern PHP, and I'm fairly sure you can do better than your predecessor.

 

In a nutshell:

  • As gizmola already said, you should use PDO and prepared statements to safely pass values to queries. mysqli is not really recommended, because it's very cumbersome and counter-intuitive.
  • Use the Password Hash API instead of MD5. This will apply a specialized hash algorithm (currently bcrypt) which is able to withstand common attacks.
  • Make sure to HTML-escape values before you insert them into an HTML context.
  • CSRF protection is also important. Store a random token in the session and include that token in every (POST) form as a hidden field. Only accept requests with a valid token.
  • Get rid of the custom session handler (yes, it replaces the default handler). Writing a correct implementation is tricky even for experienced programmers, and you don't seem to need it anyway.

I understand this is a lot to learn, and you may not get it right the first time. But you obviously take the job seriously, and that's the most important part. If you have specific questions, feel free to discuss them here.

Link to comment
Share on other sites

Just want to add after you accomplish what Jacques1 and gizmola said then regenerate the session id after the user has successfully has login. That way even if a person by chance hijacked that account the login would still be invalid. 

 

 

For example ->

    // Regenerate session ID to invalidate the old one.
    // Super important to prevent session hijacking/fixation.
    session_regenerate_id();

    $_SESSION['logged_in'] = true;

Link to comment
Share on other sites

Make that

session_regenerate_id(true);
                      ^^^^

Otherwise the old session is still intact and will contain everything you've written to it before the ID change.

 

The truth is: Implementing secure sessions is tough, because the PHP session mechanism was clearly never designed for this purpose. The session_start() function is a combination of start/adopt/resume, and you never know what you get.

  • a fresh session with a server-generated ID
  • or a fresh session with a user-provided ID that may have been set by an attacker (unless session.use_strict_mode is on) 
  • or an old session which may contain all kinds of data and also have an ID set by an attacker

What I would do is write wrapper functions to cleary distinguish between actually starting a session and resuming an old session. But that's a whole new topic.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.