SuiteCRM does not store sessions on the local server - php

I'm trying to login to the main page of SuiteCRM, an open source software that provides a CRM model for large companies, and I'm having some problems logging in.
index.php?action=Login&module=Users&login_module=Home&login_action=index (url)
On the local server I am using Wampserver 3.2.6 (64 bits), PHP 7.4.26 and MariaDB 10.3.28 database. In the line that the error indicates, only the command session_start() appears and nothing else, so when I try to log in to the system, it remains on the same screen after putting the credentials, because there is some configuration inside the SuiteCRM folders that prevents the software or the local server itself to store sessions.
index.php?action=Login&module=Users&login_module=Home&login_action=index (url)
include\MVC\SugarApplication.php (file path)
public function startSession()
{
$sessionIdCookie = isset($_COOKIE['PHPSESSID']) ? $_COOKIE['PHPSESSID'] : null;
if (isset($_REQUEST['MSID'])) {
session_id($_REQUEST['MSID']);
session_start();
if (!isset($_SESSION['user_id'])) {
if (isset($_COOKIE['PHPSESSID'])) {
self::setCookie('PHPSESSID', '', time() - 42000, '/');
}
sugar_cleanup(false);
session_destroy();
exit('Not a valid entry method');
}
} else {
if (can_start_session()) {
session_start(); // <= here is the error line #609
}
}
//set the default module to either Home or specified default
$default_module = !empty($GLOBALS['sugar_config']['default_module']) ? $GLOBALS['sugar_config']['default_module'] : 'Home';
//set session expired message if login module and action are set to a non login default
//AND session id in cookie is set but super global session array is empty
if (isset($_REQUEST['login_module']) && isset($_REQUEST['login_action']) && !($_REQUEST['login_module'] == $default_module && $_REQUEST['login_action'] == 'index')) {
if (!is_null($sessionIdCookie) && empty($_SESSION)) {
self::setCookie('loginErrorMessage', 'LBL_SESSION_EXPIRED', time() + 30, '/');
}
}
LogicHook::initialize()->call_custom_logic('', 'after_session_start');
}
What is the best alternative to solve this problem?

Related

SESSION variable is reset on redirect() in Codeigniter php

I am facing some weird issue of session variable getting reset on action redirect.
I am using Codeigniter and redirecting to dashboard action after login, I am getting data in login action after verifying credentials with DB, but when I use redirect() to redirect to dashboard, session variables gets vanished.
Admin.php
<?php class admin extends CI_Controller
{
function login()
{
$login = $this->Admin_model->login($this->input->post()); // <-- verify data and set to session
if($login)
{
$this->session->set_flashdata("success","Logged in Successfully");
var_dump($_SESSION); // <-- able to fetch data from session
// exit();
redirect("admin/dashboard");
}
else
{
$this->session->set_flashdata("error","Invalid Credentials!! Please Try Again!!");
redirect("admin");
}
}
function dashboard()
{
var_dump($_SESSION); // <-- session data is vanished and not able to get userdata('id')
exit();
if($this->session->userdata('id') != '')
{
$data['active_tab'] = "dashboard";
}
else
{
redirect("admin");
}
}
?>
Admin_model.php
<?php Class Admin_Model extends CI_Model
{
function login($data)
{
$user = $this->db->get_where("users",array("username" => $data['username'],
"password" => md5($data['password']),
"is_active" => "1")
)->row_array();
if(!empty($user))
{
$this->set_user_session($user);
return true;
}
else
{
return false;
}
}
function set_user_session($login)
{
$arr = array();
$arr["id"] = $login["id"];
$arr["username"] = $login["username"];
$this->session->set_userdata($arr);
}
?>
Tried this in xampp and wamp, all browsers but still the issue remains the same, any help would be grateful.
Which version of CodeIgniter are you working with? You can try the following steps.
Go to system/libraries/Session/Session.php
Comment session_start() by adding //. We want to relocate the sessionn_start().
Find (using ctrl + f) a comment that says Security is king. Comment out all the line under that comment until the end of the function. In my case I commented out the line number 315 - 320.
on line number 282 change this line ini_set('session.name', $params['cookie_name']); to ini_set('session.id', $params['cookie_name']);
comment out following lines
line 108 //session_set_save_handler($class, TRUE);
line 290-296
// session_set_cookie_params(
// $params['cookie_lifetime'],
// $params['cookie_path'],
// $params['cookie_domain'],
// $params['cookie_secure'],
// TRUE // HttpOnly; Yes, this is intentional and not configurable for security reasons
// );
line 305 //ini_set('session.gc_maxlifetime', $expiration);
Go to the main index.php, it is the first index.php and located in the same directory with the sub-directories 'application', 'system', 'user_guide', etc.
Put session_start() right after < ?php
Hope this can help you....
You have to use this->session->set_userdata() for setting the session. this->session-> set_ flashdata() is used for setting flash messages which are removed after next action.
The new versions of the browsers might be destroying the session because of the new cookie policy.
References
https://developers.google.com/search/blog/2020/01/get-ready-for-new-samesitenone-secure
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
Whenever the cookie is required to be sent to server, the browser sees the SameSite attribute to decide if the cookie to be sent to server or blocked. For user actions, it is sent to the server but for auto-redirects, it doesn't if SameSite is set to 'Strict' or 'Lax' (Lax is going to be the default value now).
Solution:
The cookie attribute SameSite can be set to 'None' along with specifying the 'Secure' attribute to 'true'. Setting 'Secure' attribute to 'true' would require your site to run on https. Sites running with http:// protocol will not be able to set 'Secure' cookie.
Please set the 'HttpOnly' attribute to 'true' for making it accessible for http requests to the server only.
In PHP, it can be achieved as below
session_set_cookie_params(0, '/PATH/; SameSite=None', <COOKIE_DOMAIN>, true, true);

Magento, Login Redirect Issue

When logging in to the admin panel I am redirected to a url such as follows:
http://website.com/index.php/admin120487/index/index/key/3174c9146a5ab0ed3743085e265fa2f4/
The last key parameter is changed every time.
Can you guys suggest me how to fix this. The username and password is fine. But when submit it goes to this url with login page.
The issue is related to the php version. My Php version on server is 7.0 Something.
Now update and comment your files with following code
/public_html/app/code/core/Mage/Core/Model/Session/Abstract.php
public function renewSession()
{
/*$this->getCookie()->delete($this->getSessionName());
$this->regenerateSessionId();
$sessionHosts = $this->getSessionHosts();
$currentCookieDomain = $this->getCookie()->getDomain();
if (is_array($sessionHosts)) {
foreach (array_keys($sessionHosts) as $host) {
// Delete cookies with the same name for parent domains
if (strpos($currentCookieDomain, $host) > 0) {
$this->getCookie()->delete($this->getSessionName(), null, $host);
}
}
}*/
return $this;
}

PHP $_SESSION variables are not being passed between pages

I am working on a school project where I need my .php pages communicating. I have header.php where I set connection to the database and start the session. In order to start the session only once, I've used this:
if(session_id() == '') {
session_start();
}
PHP version is PHP 5.3.10-1 ubuntu3.18 with Suhosin-Patch (cli)
I am trying to pass some $_SESSION variables between pages, but they keep being unset when I try to use them on a page that doesn't set them.
I see many people have complained about this, but I still can't find the solution.
login-form.php
<?php
if (isset($_SESSION["login-error"])) {
echo '<p>'.$_SESSION["login-error"].'</p>';
}
?>
login.php
$_SESSION["login-error"]= "Username or password incorrect";
There is a code snippet of what is not working for me.
Thanks
You can try this.
In your function file put this
function is_session_started()
{
if ( php_sapi_name() !== 'cli' ) {
if ( version_compare(phpversion(), '5.4.0', '>=') ) {
return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
} else {
return session_id() === '' ? FALSE : TRUE;
}
}
return FALSE;
}
Then you can run this in every page you want session started
if ( is_session_started() === FALSE ) session_start();
With this I think you should be good to go on starting your session across pages. Next is to ensure you set a session to a value. If you are not sure what is unsetting your sessions you can try var_dump($_SESSION) at different parts of your code so you be sure at what point it resets then know how to deal with it.
The variables are probable not set, because you haven't activate the session variables with session_start().
session_id() == '' is not a correct conditional . Use instead:
if (!isset($_SESSION)) { session_start();}
if you have session started then you can set a session variable
if (!isset($_SESSION["login-error"])) { $_SESSION["login-error"]= "Username or password incorrect";}
Before you call $_SESSION["login-error"], type session_start(), just for testing, to find when the session signal is missing. You said
PHP $_SESSION variables are not being passed between pages
session_start() and SESSION variables needs to be included at the beginning of EVERY page or at the place where SESSION variables are being called (through a common file, bootstrap, config or sth) at the beginning of EVERY page. ie the command to read those data from the server is needed.
Since my header.php file included "connection.php" file, I put
session_start();
at the beginning of connection.php and deleted it from header.php file. Now it works fine. Thanks all for your help!
PHP sessions rely on components of HTTP, like Cookies and GET variables, which are clearly not available when you're calling a script via the CLI. You could try faking entries in the PHP superglobals, but that is wholly inadvisable. Instead, implement a basic cache yourself.
<?php
class MyCache implements ArrayAccess {
protected $cacheDir, $cacheKey, $cacheFile, $cache;
public function __construct($cacheDir, $cacheKey) {
if( ! is_dir($cacheDir) ) { throw new Exception('Cache directory does not exist: '.$cacheDir); }
$this->cacheDir = $cacheDir;
$this->cacheKey = $cacheKey;
$this->cacheFile = $this->cacheDir . md5($this->cacheKey) . '.cache';
// get the cache if there already is one
if( file_exists($this->cacheFile) ) {
$this->cache = unserialize(file_get_contents($this->cacheFile));
} else {
$this->cache = [];
}
}
// save the cache when the object is destructed
public function __destruct() {
file_put_contents($this->cacheFile, serialize($this->cache));
}
// ArrayAccess functions
public function offsetExists($offset) { return isset($this->cache[$offset]); }
public function offsetGet($offset) { return $this->cache[$offset]; }
public function offsetSet($offset, $value) { $this->cache[$offset] = $value; }
public function offsetUnset($offset) { unset($this->cache[$offset]); }
}
$username = exec('whoami');
$c = new MyCache('./cache/', $username);
if( isset($c['foo']) ) {
printf("Foo is: %s\n", $c['foo']);
} else {
$c['foo'] = md5(rand());
printf("Set Foo to %s", $c['foo']);
}
Example runs:
# php cache.php
Set Foo to e4be2bd956fd81f3c78b621c2f4bed47
# php cache.php
Foo is: e4be2bd956fd81f3c78b621c2f4bed47
This is pretty much all PHP's sessions do, except a random cache key is generated [aka PHPSESSID] and is set as a cookie, and the cache directory is session.save_path from php.ini.

PHP Mobile Detection

I have a problem with the Mobile Detection Script.
There are two scenarios:
First the script should detect if it's a mobile or not. If mobile, than redirect to another page (this works fine).
The second query should determine, if the person is on the root page or not. If it's not the root page, the layout should be the classic one. (no redirection)
But when I add this line there won't be anymore redirection, even if I open the root page on a mobile.
I also tried to destroy the session on the google_mobile.php (redirected page) and set the $_SESSION['layoutType'] = 'mobile', but anyway the session is set to classic when I open the root page.
Thanks for your help!
Here is the script:
session_start();
require_once 'Mobile_Detect.php';
function layoutTypes() {
return array('classic', 'mobile');
}
function initLayoutType() {
// Safety check.
if (!class_exists('Mobile_Detect'))
return 'classic';
$detect = new Mobile_Detect;
$isMobile = $detect->isMobile();
$layoutTypes = layoutTypes();
// Set the layout type.
if (isset($_GET['layoutType'])) {
$layoutType = $_GET['layoutType'];
} else {
if (empty($_SESSION['layoutType'])) {
$layoutType = ($isMobile ? 'mobile' : 'classic');
} else {
$layoutType = $_SESSION['layoutType'];
}
//check if it's the root page
if ($_SERVER['REQUEST_URI'] != "/")
$layoutType = 'classic';
}
// Fallback. If everything fails choose classic layout.
if (!in_array($layoutType, $layoutTypes))
$layoutType = 'classic';
// Store the layout type for future use.
$_SESSION['layoutType'] = $layoutType;
return $layoutType;
}
$layoutType = initLayoutType();
if ($_SESSION['layoutType'] == 'mobile') {
header("Location: www.example.com/google_mobile.php");
exit;
}
I've tested your code, it seems to work as you described. I'd guess it is a session issue.
session_destroy() does not clear your previous session state in the immediate session. That means your $_SESSION would still be "dirty" in a script even if session_destroy() is the first line in it. It's safer to clear cookies from your browser instead.
One other possible problem would be query string. You're checking the REQUEST_URI and it includes any query string on URI. "/?foo=bar" is certainly not "/". You may want to check SCRIPT_NAME (i.e. $_SERVER['SCRIPT_NAME'] == 'index.php) instead.

PHP Session believes it's being hijacked unless an echo is performed

I'm writing a simple website which allows a user to login, fill out a form which is submitted to a database and then log out. In order to manage the session, I used the session manager which is described by TreeHouse on the following page: http://blog.teamtreehouse.com/how-to-create-bulletproof-sessions
In order to protect against hijacking, the client's IP address and user agent are stored in the session variable and compared to the server's values for these properties on each page. If they don't match, then it is assumed that the session has been hijacked and it is reset.
The implementation seems to work on my local machine without any issues, but when I uploaded it to the server, each page refresh causes the preventHijacking() function to return false (meaning it believes the session has been hijacked). However, if I echo any text within that function, the problem mysteriously disappears and the whole thing works as I expect it to (except for the bit of echoed text which is now displayed above my form :P).
I haven't a clue why this would be the case and I can't figure out how to fix it. The session manager code is below. At the start of each page, I use this to start the session and then each page simply uses or sets whatever variables it requires. If anyone could suggest why the function always returns false unless it echoes text and perhaps suggest what modification I need to make so that it will behave in the expected manner, I'd really appreciate it.
<?php
class SessionManager {
protected static $timeout = 600; // Time before automatic logout for the session
static function sessionStart($name, $limit=0, $path='/', $domain=null, $secure=null) {
// Set the cookie name before we start
session_name($name.'_Session');
// Set the domain to default to the current domain
$domain = isset($domain)? $domain : $_SERVER['SERVER_NAME'];
// Set the default secure value to whether the site is being accessed with SSL
$https = isset($secure)? $secure : isset($_SERVER['HTTPS']);
// Set the cookie settings and start the session
session_set_cookie_params($limit, $path, $domain, $secure, True);
session_start();
// Make sure the session hasn't expired and destroy it if it has
if(self::validateSession()) {
// Check to see if the session is new or a hijacking attempt
if(!self::preventHijacking()) {
// Reset session data and regenerate ID
$_SESSION=array();
$_SESSION['IPaddress'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['userAgent'] = $_SERVER['HTTP_USER_AGENT'];
self::regenerateSession();
// Give a 5% chance of the session ID changing on any request
} else if (rand(1, 100) <= 5) {
self::regenerateSession();
}
$_SESSION['LAST_ACTIVITY'] = time();
} else {
$_SESSION = array();
session_destroy();
session_start();
}
}
static function preventHijacking() {
if(!isset($_SESSION['IPaddress']) || !isset($_SESSION['userAgent'])) {
return false;
}
if($_SESSION['IPaddress'] != $_SERVER['REMOTE_ADDR']) {
return false;
}
if($_SESSION['userAgent'] != $_SERVER['HTTP_USER_AGENT']) {
return false;
}
return true;
}
static function regenerateSession() {
// If this session is obsolete, it means that there already is a new id
if(isset($_SESSION['OBSOLETE']) && $_SESSION['OBSOLETE'] === True) {
return;
}
// Set current session to expire in 10 seconds
$_SESSION['OBSOLETE'] = True;
$_SESSION['EXPIRES'] = time() + 10;
// Create new session without destroying the old one
session_regenerate_id(false);
// Grab current session ID and close both sessions to allow other scripts to use them
$newSession = session_id();
session_write_close();
// Set session ID to the new one and start it back up again
session_id($newSession);
session_start();
// Now we unset the obsolete and expiration values for the session we want to keep
unset($_SESSION['OBSOLETE']);
unset($_SESSION['EXPIRES']);
}
static protected function validateSession() {
// Check if something went wrong
if(isset($_SESSION['OBSOLETE']) && !isset($_SESSION['EXPIRES'])) {
return false;
}
// Test if this is an old session which has expired
if(isset($_SESSION['EXPIRES']) && $_SESSION['EXPIRES'] < time()) {
return false;
}
// Check if the user's login has timed out
if(isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY']) > self::$timeout) {
return false;
}
return true;
}
}
?>
I could be way out here (it's been a while) but that sounds like the buffer containing the headers isn't being flushed for some reason. Providing body would force them to be flushed, so maybe not providing the body doesn't flush?
Try putting ob_end_flush(); in there before you return. That may fix it.

Categories