• Uncategorized

About php : Why-does-codeigniter-Linux-server-throws-unserialize-session-data-error-when-user-tries-to-login

Question Detail

I am developing an app using CodeIgniter and I have deployed this app on a linux server, the issues I am facing is this error
ERROR - 2022-01-06 11:48:16 --> Severity: Notice --> unserialize(): Error at offset 122 of 167 bytes /var/www/htmlaplib_core/libraries/Session.php 740 which prevent any user from logging in however on my local development environment I do not get this error, I have tried to find solutions on the internet but still I am not able to get collect solution.

This is the code that causes the issues during deployment.

function _unserialize($data)
{
    
    $data = @unserialize(strip_slashes($data));
    if (is_array($data))
    {
        foreach ($data as $key => $val)
        {
            if (is_string($val))
            {
                $data[$key] = str_replace('{{slash}}', '\\', $val);
            }
        }

        return $data;
    }

    return (is_string($data)) ? str_replace('{{slash}}', '\\', $data) : $data;
}

I will appreciate any help that I can get

Especially this line $data = @unserialize(strip_slashes($data));

This is the output of variable $data before @unserialize()

  • a:15:{s:10:"session_id";s:32:"aef2d2d8a8282132c6ebae6ccc4b94a8";s:10:"ip_address";s:3:"::1";s:10:"user_agent";s:114:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36";s:13:"last_activity";i:1641453560;s:9:"user_data";s:0:"";s:4:"LANG";s:2:"en";s:8:"identity";s:16:"[email protected]";s:8:"username";s:16:"[email protected]";s:5:"email";s:16:"admin@gmail";s:7:"user_id";s:1:"2";s:14:"old_last_login";s:10:"1641452323";s:14:"institution_id";s:1:"0";s:20:"employer_category_id";a:0:{}s:13:"user_group_id";s:1:"1";s:13:"employer_name";N;}

Question Answer

The problem most likely lies in some invalid serialization data due to invalid length.

A solution for this would be to recalculate the number of items as well as the length of these items in the serialized data.

$recalculated_data = preg_replace_callback( '!s:(\d+):"(.*?)";!', function( $match ) {      
    return ( $match[1] == strlen( $match[2] ) ) ? $match[0] : 's:' . strlen( $match[2] ) . ':"' . $match[2] . '";';
}, $data );

unserialize( $recalculated_data );

Also please refrain from using @ in your code, as this will prevent (important) warnings from showing.

More info on the serialization invalid length: How to repair a serialized string which has been corrupted by an incorrect byte count length?

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.