warning in session_start() in php 7.1 - php

my script has a problem and gives me this warning:
Warning: session_start(): Failed to read session data: user (path:
/Users/soroush/Documents/www/new/tmp/session) in
/Users/soroush/Documents/www/new/include/class.session.php on line 35
this is my class:
class SecureSessionHandler extends SessionHandler {
protected $key, $name, $cookie;
public function __construct($name = 'MY_SESSION', $cookie = [])
{
$this->key = SESSION_KEY;
$this->name = $name;
$this->cookie = $cookie;
$this->cookie += [
'lifetime' => 0,
'path' => ini_get('session.cookie_path'),
'domain' => ini_get('session.cookie_domain'),
'secure' => isset($_SERVER['HTTPS']),
'httponly' => true
];
$this->setup();
}
private function setup()
{
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
session_name($this->name);
session_set_cookie_params(
$this->cookie['lifetime'],
$this->cookie['path'],
$this->cookie['domain'],
$this->cookie['secure'],
$this->cookie['httponly']
);
}
public function start()
{
if (session_id() === '') {
if (session_start()) {
return mt_rand(0, 4) === 0 ? $this->refresh() : true; // 1/5
}
}
return false;
}
public function forget()
{
if (session_id() === '') {
return false;
}
$_SESSION = [];
setcookie(
$this->name,
'',
time() - 42000,
$this->cookie['path'],
$this->cookie['domain'],
$this->cookie['secure'],
$this->cookie['httponly']
);
return session_destroy();
}
public function refresh()
{
return session_regenerate_id(true);
}
public function read($id)
{
$data = openssl_decrypt(parent::read($id),'AES256',$this->key);
return $data;
}
public function write($id, $data)
{
return parent::write($id, openssl_encrypt(parent::read($id),'AES256',$this->key));
}
public function isExpired($ttl = 30)
{
$last = isset($_SESSION['_last_activity'])
? $_SESSION['_last_activity']
: false;
if ($last !== false && time() - $last > $ttl * 60) {
return true;
}
$_SESSION['_last_activity'] = time();
return false;
}
public function isFingerprint()
{
$hash = md5(
$_SERVER['HTTP_USER_AGENT'] .
(ip2long($_SERVER['REMOTE_ADDR']) & ip2long('255.255.0.0'))
);
if (isset($_SESSION['_fingerprint'])) {
return $_SESSION['_fingerprint'] === $hash;
}
$_SESSION['_fingerprint'] = $hash;
return true;
}
public function isValid()
{
return ! $this->isExpired() && $this->isFingerprint();
}
public function get($name)
{
$parsed = explode('.', $name);
$result = $_SESSION;
while ($parsed) {
$next = array_shift($parsed);
if (isset($result[$next])) {
$result = $result[$next];
} else {
return null;
}
}
return $result;
}
public function put($name, $value)
{
$parsed = explode('.', $name);
$session =& $_SESSION;
while (count($parsed) > 1) {
$next = array_shift($parsed);
if ( ! isset($session[$next]) || ! is_array($session[$next])) {
$session[$next] = [];
}
$session =& $session[$next];
}
$session[array_shift($parsed)] = $value;
}
}
and i use this class like this:
$session = new SecureSessionHandler();
ini_set('session.save_handler', 'files');
session_set_save_handler($session, true);
session_save_path(SITE_PATH.'tmp/session');
$session->start();
if ( ! $session->isValid(5)) {
$session->destroy();
die();
}
$session->put('site.langu', $lang->lang);
but it give me a warning in php 7.1
i use a mac os system and do this works
give 0777 permission to session folder
change chown with php running group and user
what should I do to fix this warning?
i solved this problem with this change:
public function read($id)
{
return (string)openssl_decrypt (parent::read($id) , "aes-256-cbc", $this->key);
}
public function write($id, $data)
{
return parent::write($id, openssl_encrypt($data, "aes-256-cbc", $this->key));
}
viva google :))

Related

PHP sessions error

I user opencart v2.3.0.2 and after finished my site I use a scanner to scan my website but after while I get this error :
Fatal error: session_set_save_handler(): Session handler's function
table is corrupt in \system\library\session.php on line 16
I have try to add this in my php.ini
session.save_path = "/temp";
but I still get the same error. I use XAMPP.
the session file :
<?php
class Session {
public $session_id = '';
public $data = array();
public function __construct($adaptor = 'native') {
$class = 'Session\\' . $adaptor;
if (class_exists($class)) {
$this->adaptor = new $class($this);
} else {
throw new \Exception('Error: Could not load session adaptor ' . $adaptor . ' session!');
}
if ($this->adaptor) {
session_set_save_handler($this->adaptor);
}
if ($this->adaptor && !session_id()) {
ini_set('session.use_only_cookies', 'Off');
ini_set('session.use_cookies', 'On');
ini_set('session.use_trans_sid', 'Off');
ini_set('session.cookie_httponly', 'On');
if (isset($_COOKIE[session_name()]) && !preg_match('/^[a-zA-Z0-9,\-]{22,52}$/', $_COOKIE[session_name()])) {
exit('Error: Invalid session ID!');
}
session_set_cookie_params(0, '/');
session_start();
}
}
public function start($key = 'default', $value = '') {
if ($value) {
$this->session_id = $value;
} elseif (isset($_COOKIE[$key])) {
$this->session_id = $_COOKIE[$key];
} else {
$this->session_id = $this->createId();
}
if (!isset($_SESSION[$this->session_id])) {
$_SESSION[$this->session_id] = array();
}
$this->data = &$_SESSION[$this->session_id];
if ($key != 'PHPSESSID') {
setcookie($key, $this->session_id, ini_get('session.cookie_lifetime'), ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly'));
}
return $this->session_id;
}
public function getId() {
return $this->session_id;
}
public function createId() {
if (version_compare(phpversion(), '5.5.4', '>') == true) {
return $this->adaptor->create_sid();
} elseif (function_exists('random_bytes')) {
return substr(bin2hex(random_bytes(26)), 0, 26);
} elseif (function_exists('openssl_random_pseudo_bytes')) {
return substr(bin2hex(openssl_random_pseudo_bytes(26)), 0, 26);
} else {
return substr(bin2hex(mcrypt_create_iv(26, MCRYPT_DEV_URANDOM)), 0, 26);
}
}
public function destroy($key = 'default') {
if (isset($_SESSION[$key])) {
unset($_SESSION[$key]);
}
setcookie($key, '', time() - 42000, ini_get('session.cookie_path'), ini_get('session.cookie_domain'));
}
}
not important section ://
blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla//
Just restart the apache & mysql. It will solve the error.

custom session_handler broken with php7 (session_set_save_handler)

After updating to PHP7 I have some problems with my applications sessionhandling.
It doesn't seem to be a big problem but PHP throws this error everytime:
[18-Jun-2016 20:49:10 UTC] PHP Warning: session_decode(): Session is not active. You cannot decode session data in /var/www/app/phpsessionredis.php on line 90
The session_handler is nothing special. It stores JSONified sessiondata to redis etc.
class phpsessionredis implements \SessionHandlerInterface {
public function __construct( &$redis ) {
$this->__rc = $redis;
}
public function open($savePath, $sessionName) {
return true;
}
public function destroy($id) {
try { $this->__rc->del($id); }
catch (\RedisException $e) { return false; }
}
public function close() {
return true;
}
public function write($id, $data) {
session_decode($data); // throws an error
try{
$this->__rc->setex( $id, 3600, json_encode($_SESSION) );
} catch (\RedisException $e) { return false; }
return true;
}
public function read($id) {
try {
$r = $this->__rc
->multi()
->get($id)
->expire($id, 3600)
->exec();
} catch (\RedisException $e) { return false; }
$_SESSION = json_decode( $r[0], true );
if( isset( $_SESSION ) && ! empty( $_SESSION ) && $_SESSION != null ){
return session_encode();
}
return '';
}
public function gc($maxLifetime) {
return true;
}
}
$sessionhandler = new phpsessionredis( $redis );
session_set_save_handler($sessionhandler);
ob_start();
session_start();
Any help is welcome.
I've got the same issue when updating to PHP7.
You get that warning because session_decode() needs an active session, it will populate $_SESSION.
That's not needed, you only want to unserialize the data to be stored into Redis.
This is the best solution i've found.
You can use this class to unserialize the session.
<?php
class Session {
public static function unserialize($session_data) {
$method = ini_get("session.serialize_handler");
switch ($method) {
case "php":
return self::unserialize_php($session_data);
break;
case "php_binary":
return self::unserialize_phpbinary($session_data);
break;
default:
throw new Exception("Unsupported session.serialize_handler: " . $method . ". Supported: php, php_binary");
}
}
private static function unserialize_php($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
if (!strstr(substr($session_data, $offset), "|")) {
throw new Exception("invalid data, remaining: " . substr($session_data, $offset));
}
$pos = strpos($session_data, "|", $offset);
$num = $pos - $offset;
$varname = substr($session_data, $offset, $num);
$offset += $num + 1;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
private static function unserialize_phpbinary($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
$num = ord($session_data[$offset]);
$offset += 1;
$varname = substr($session_data, $offset, $num);
$offset += $num;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
}
?>
Your write() will be:
public function write($id, $data) {
$session_data = Session::unserialize($data);
try{
$this->__rc->setex( $id, 3600, json_encode($session_data) );
} catch (\RedisException $e) { return false; }
return true;
}
I don't know if this should be handled as a correct answer but it is a solution that seems to work.
ini_set('session.serialize_handler', 'php_serialize');
With this option we don't need session_decode and can replace it with unserialze() within the write method.
public function write($id, $data) {
$data = unserialize($data);
/** do something **/
}
For me this looks like a workaround.

PHP Sessions on Windows and Linux

I've faced this problem maybe a week ago and still unable to figure out what is wrong.
I have 2 machines, one is running Windows, the other is running Debian 8.
So the thing is:
On Windows code executes as it should
On Linux it is a total mess
The problem is with sessions, i'm unable to make them work on Linux.
How they work:
Client Access Website --> PHP Creates Session --> Write to DB (ID, Key, Data) --> Get DB Session --> Check if it correct --> Update Data --> User leaves/log out --> Delete session
What i have:
On Windows it works exactly as i described above
On Linux script keep adding values to DB (ID and KEY are identical) and not deleting them after logout
From here i cant use authorization on Linux, but it works perfectly on Windows.
Here is a Sessions Class:
<?php
Class Session
{
public static $DBConnection;
private static $SessionCreated = false;
private static $Salt;
public function __construct($Database)
{
session_set_save_handler(array($this, 'Open'), array($this, 'Close'), array($this, 'Read'), array($this, 'Write'), array($this, 'Destroy'), array($this, 'GarbageCollector'));
register_shutdown_function('session_write_close');
Session::$DBConnection = $Database::$Connection;
$FileLocation = getcwd().DS.'Core'.DS.'Libraries'.DS.'FreedomCore';
$Files = scandir($FileLocation);
for($i = 0; $i < 4; $i++)
unset($Files[$i]);
if(!empty($Files))
{
Session::$Salt = file_get_contents($FileLocation.DS.$Files[4]);
}
else
{
$RandomFileName = substr( "abcdefghijklmnopqrstuvwxyz" ,mt_rand( 0 ,25 ) ,1 ) .substr( md5( time( ) ) ,1 );
$RandomSalt = Session::GenerateRandomSalt();
file_put_contents($FileLocation.DS.$RandomFileName, $RandomSalt);
Session::$Salt = $RandomSalt;
}
}
public static function UpdateSession($Data)
{
if (session_status() != PHP_SESSION_NONE)
foreach($Data as $key=>$value)
$_SESSION[$key] = $value;
}
public static function SessionStatus()
{
if(session_status() == PHP_SESSION_NONE)
return false;
else
return true;
}
private static function GenerateRandomSalt()
{
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789*+|/-';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $charactersLength; $i++)
$randomString .= $characters[rand(0, $charactersLength - 1)];
return $randomString;
}
public static function GenerateCSRFToken()
{
$InitialString = "abcdefghijklmnopqrstuvwxyz1234567890";
$PartOne = substr(str_shuffle($InitialString),0,8);
$PartTwo = substr(str_shuffle($InitialString),0,4);
$PartThree = substr(str_shuffle($InitialString),0,4);
$PartFour = substr(str_shuffle($InitialString),0,4);
$PartFive = substr(str_shuffle($InitialString),0,12);
$FinalCode = $PartOne.'-'.$PartTwo.'-'.$PartThree.'-'.$PartFour.'-'.$PartFive;
$_SESSION['generated_csrf'] = $FinalCode;
return $FinalCode;
}
public static function ValidateCSRFToken($Token)
{
if(isset($Token) && $Token == $_SESSION['generated_csrf'])
{
unset($_SESSION['generated_csrf']);
return true;
}
else
return false;
}
public static function UnsetKeys($Keys)
{
foreach($Keys as $Key)
unset($_SESSION[$Key]);
}
public static function Start($SessionName, $Secure)
{
$HTTPOnly = true;
$Session_Hash = 'sha512';
if(in_array($Session_Hash, hash_algos()))
ini_set('session.hash_function', $Session_Hash);
ini_set('session.hash_bits_per_character', 6);
ini_set('session.use_only_cookies', 1);
$CookieParameters = session_get_cookie_params();
session_set_cookie_params($CookieParameters["lifetime"], $CookieParameters["path"], $CookieParameters["domain"], $Secure, $HTTPOnly);
session_name($SessionName);
session_start();
//session_regenerate_id(true);
Session::$SessionCreated = true;
}
static function Open()
{
if(is_null(Session::$DBConnection))
{
die("Unable to establish connection with database for Secure Session!");
return false;
}
else
return true;
}
static function Close()
{
Session::$DBConnection = null;
return true;
}
static function Read($SessionID)
{
$Statement = Session::$DBConnection->prepare("SELECT data FROM sessions WHERE id = :sessionid LIMIT 1");
$Statement->bindParam(':sessionid', $SessionID);
$Statement->execute();
$Result = $Statement->fetch(PDO::FETCH_ASSOC);
$Key = Session::GetKey($SessionID);
$Data = Session::Decrypt($Result['data'], $Key);
return $Data;
}
static function Write($SessionID, $SessionData)
{
$Key = Session::GetKey($SessionID);
$Data = Session::Encrypt($SessionData, $Key);
$TimeNow = time();
$Statement = Session::$DBConnection->prepare('REPLACE INTO sessions (id, set_time, data, session_key) VALUES (:sessionid, :creation_time, :session_data, :session_key)');
$Statement->bindParam(':sessionid', $SessionID);
$Statement->bindParam(':creation_time', $TimeNow);
$Statement->bindParam(':session_data', $Data);
$Statement->bindParam(':session_key', $Key);
$Statement->execute();
return true;
}
static function Destroy($SessionID)
{
$Statement = Session::$DBConnection->prepare('DELETE FROM sessions WHERE id = :sessionid');
$Statement->bindParam(':sessionid', $SessionID);
$Statement->execute();
Session::$SessionCreated = false;
setcookie("FreedomCoreLanguage", null, time()-3600);
setcookie("FreedomCore", null, time()-3600);
return true;
}
private static function GarbageCollector($Max)
{
$Statement = Session::$DBConnection->prepare('DELETE FROM sessions WHERE set_time < :maxtime');
$OldSessions = time()-$Max;
$Statement->bindParam(':maxtime', $OldSessions);
$Statement->execute();
return true;
}
private static function GetKey($SessionID)
{
$Statement = Session::$DBConnection->prepare('SELECT session_key FROM sessions WHERE id = :sessionid LIMIT 1');
$Statement->bindParam(':sessionid', $SessionID);
$Statement->execute();
$Result = $Statement->fetch(PDO::FETCH_ASSOC);
if($Result['session_key'] != '')
return $Result['session_key'];
else
return hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
}
private static function Encrypt($SessionData, $SessionKey)
{
$Salt = Session::$Salt;
$SessionKey = substr(hash('sha256', $Salt.$SessionKey.$Salt), 0, 32);
$Get_IV_Size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$IV = mcrypt_create_iv($Get_IV_Size, MCRYPT_RAND);
$Encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $SessionKey, $SessionData, MCRYPT_MODE_ECB, $IV));
return $Encrypted;
}
private static function Decrypt($SessionData, $SessionKey)
{
$Salt = Session::$Salt;
$SessionKey = substr(hash('sha256', $Salt.$SessionKey.$Salt), 0, 32);
$Get_IV_Size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$IV = mcrypt_create_iv($Get_IV_Size, MCRYPT_RAND);
$Decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $SessionKey, base64_decode($SessionData), MCRYPT_MODE_ECB, $IV);
return $Decrypted;
}
}
?>
Here is how session initialized:
if(session_status() == PHP_SESSION_NONE)
{
$Session = new Session($Database);
$InstallationIsInProgress = false;
if(isset($_COOKIE['FreedomCore']))
Session::Start('FreedomCore', false);
}
Folder with scripts on github
Important files are Database.FreedomCore.php and Sessions.FreedomCore.php
The main question is:
Why exactly the same code works perfectly on Windows, and cant to work at all on Linux?
P.S. Servers running exactly the same versions of Apache and PHP
Thanks for any help!

New Session created on every page refresh

I am working on a PHP application wherein, i have written a Session Class. However, i am running into a strange issue. Everytime i refresh the page a new session is created.
Also, C:\xampp\tmp is writable (i am on xampp) and session_id() always returns null.
Below is my Session Class
<?php
/**
* Class and Function List:
* Function list:
* - __construct()
* - start()
* - stop()
* - generate_sid()
* - set()
* - delete()
* - get()
* - check()
* - flash()
* Classes list:
* - Session
*/
class Session
{
public $flashElements = array();
public function __construct($autoStart = true)
{
$this->started = isset($_SESSION);
e("The Session Id is " . session_id());
if (!is_writable(session_save_path()))
{
echo 'Session save path "' . session_save_path() . '" is not writable!';
}
e(session_save_path());
if ($this->started && $autoStart === false)
{
$this->start();
}
e("The Session Id is " . session_id());
}
public function start()
{
if (!$this->started)
{
session_id($this->generate_sid());
session_start();
$this->started = true;
}
}
public function stop($clearCookie = true, $clearData = true)
{
if ($this->started)
{
if (($clearCookie) && Configure::get('session.useCookie'))
{
$params = session_get_cookie_params();
setcookie(session_name() , '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
}
if ($clearData)
{
$_SESSION = array();
}
session_destroy();
session_write_close();
$this->started = false;
}
}
public function generate_sid($chars = 100, $alpha = true, $numeric = true, $symbols = true, $timestamp = true)
{
if ($chars < 0 || !is_numeric($chars))
{
return false;
}
$salt = Configure::get('security.salt');
if ($alpha)
{
$salt.= 'abcdefghijklmnopqrstuvwxyz';
}
if ($numeric)
{
$salt.= '1234567890';
}
if ($symbols)
{
$salt.= '-_';
}
$sid = null;
for ($i = 1;$i <= $chars;$i++)
{
$sid.= $saltmt_rand(0, strlen($salt) - 1);
if (mt_rand(0, 1) === 1)
{
$sid
{
strlen($sid) - 1} = strtoupper($sid
{
strlen($sid) - 1});
}
}
if ($timestamp)
{
$sid.= time();
}
return $sid;
}
public function set($keyword, $value)
{
$_SESSION[$keyword] = $value;
}
public function delete($keyword)
{
unset($_SESSION[$keyword]);
$this->flashElements[$keyword] = null;
unset($this->flashElements[$keyword]);
}
public function get($keyword)
{
$returnVar = isset($_SESSION[$keyword]) ? $_SESSION[$keyword] : false;
if (isset($this->flashElements[$keyword]))
{
$this->delete($keyword);
}
return $returnVar;
}
public function check($keyword)
{
return isset($_SESSION[$keyword]) ? true : false;
}
public function flash($value)
{
$this->set('flash', $value);
$this->flashElements['flash'] = $value;
}
}
Please suggest where am i going wrong
I think you're not creating a session because you only call the start function when
$autostart === false
Where it is true by default;
Silly of me. Got it working.
changed the below code in __construct() function
if ($this->started == false && $autoStart != false)
{
$this->start();
}
Thanks Guys!

How to return true/false from a function in php

How can I use the return true/false for another function?
<?php
class Bet {
private $Client;
private $Secret;
private $Server;
public function __construct() {
$this->Client = md5(uniqid(rand(), true));
$this->Secret = md5(uniqid(rand(), true));
$this->Server = md5(uniqid(rand(), true));
}
public function Bet($Type, $Chance) {
if($Type == 'auto') {
$hash = hash('sha512', $this->Client . $this->Secret . $this->Server);
$Result = round(hexdec(substr($hash, 0, 8)) / 42949672.95, 2);
if($Result < $Chance) {
return true;
} else {
return false;
}
}
}
}
?>
Heres what I been trying:
if(isset($_POST['chance'], $_POST['bet'])) {
print_r($Bet->Bet('auto', $_POST['chance']));
if($Bet == true)
{
return "1";
} else {
return "2";
}
}
But I can't see to get inside the if state.
try this
if($Bet)
{
return "1";
} else {
return "2";
}
}
You have to instantiate your class:
$bet = new Bet($type, $chance);
but a constructor cannot return a value like you are doing.
try something like this:
public function betTest() { return what you want; }
[...]
if ($bet->betTest()) { return 1; } else { return 2; }
or use a static method:
public static function betTest() { /.../ }
if (Bet::betTest()) { ... }
Based on your code:
<?php
class Bet {
private $Client;
private $Secret;
private $Server;
private $result;
public function __construct($Type, $Chance) {
$this->Client = md5(uniqid(rand(), true));
$this->Secret = md5(uniqid(rand(), true));
$this->Server = md5(uniqid(rand(), true));
if($Type == 'auto') {
$hash = hash('sha512', $this->Client . $this->Secret . $this->Server);
$Result = round(hexdec(substr($hash, 0, 8)) / 42949672.95, 2);
if($Result < $Chance) {
$this->result = true;
} else {
$this->result = false;
}
}
}
/**
* #return boolean
*/
public function isReturnLessThanChance() { return $this->result; }
}
$bet = new Bet("", "");
if ($bet->isResultLessThanChance()) {
return 1;
else
return 2;
you can try this also.
if($Bet === true) { return "1"; } else { return "2"; }
=== check data type as well as value. then (true !== 1).

Categories