I have developed a PHP web application that used cookie-based sessions and it was all working fine - until I realised that it won't work in browsers that have third party cookies disabled (because the script is going to be loaded in an iframe on another website/domain).
So I decided to switch over to URL-based sessions (which I presume will be safe as, because the script is in an iframe, there will be no visible URL for the user to share or bookmark, etc.).
However, for some reason, since I switched to domain-based sessions, each page in my web application is using a different session ID.
Here's my code...
ini_set("session.use_cookies", 0);
ini_set("session.use_only_cookies", 0);
ini_set("session.use_trans_sid", 1);
ini_set("session.cache_limiter", "");
session_start();
echo "<p>Session ID: " . session_id() . "</p>"; // Test output
...which is the very first thing to be called on each page (with no previous output that I'm aware of).
The first page in my web app contains a form and I see that the required hidden session ID input is automatically added to it by PHP:
<input type="hidden" name="PHPSESSID" value="m4jbeec47uplnf95ue2h244a02" />
But the session ID reported by the next page (that the form submits to) is
Session ID: iiovfkrf3hesj1um5orasv7it6
Also, when I load the first page using https:// (instead of http://), submitting the form results in the same page being reloaded (rather than the next page being loaded).
What I've already tried:
ini_set("session.cookie_secure", 0);
and
ini_set("session.cookie_secure", 1);
and
ini_set('session.gc_maxlifetime', 30 * 60); // expires in 30 minutes
and (at the end of the script)
session_write_close();
and removing
ini_set("session.cache_limiter", "");
From phpinfo()
:
session.auto_start Off Off
session.cache_expire 180 180
session.cache_limiter nocache nocache
session.cookie_domain no value no value
session.cookie_httponly Off Off
session.cookie_lifetime 0 0
session.cookie_path / /
session.cookie_secure Off Off
session.entropy_file no value no value
session.entropy_length 0 0
session.gc_divisor 1000 1000
session.gc_maxlifetime 1440 1440
session.gc_probability 1 1
session.hash_bits_per_character 5 5
session.hash_function 0 0
session.name PHPSESSID PHPSESSID
session.referer_check no value no value
session.save_handler files files
session.save_path /tmp /tmp
session.serialize_handler php php
session.upload_progress.cleanup On On
session.upload_progress.enabled On On
session.upload_progress.freq 1% 1%
session.upload_progress.min_freq 1 1
session.upload_progress.name PHP_SESSION_UPLOAD_PROGRESS PHP_SESSION_UPLOAD_PROGRESS
session.upload_progress.prefix upload_progress_ upload_progress_
session.use_cookies On On
session.use_only_cookies On On
session.use_strict_mode Off Off
session.use_trans_sid 0 0
Any ideas?
session_regenerate_id() will replace the current session id with a new one, and keep the current session information. When session. use_trans_sid is enabled, output must be started after session_regenerate_id() call. Otherwise, old session ID is used.
It's not a firm uniqueness condition especially from a security perspective.
Your session ID can either be passed through the URL or through the use of a cookie. Although it is preferable for security reasons to pass the session ID through a cookie so that it is hidden from the human eye, if cookies are not enabled then the alternative is to use the URL. This setting is determined in your php.
session_id() is used to get or set the session id for the current session. The constant SID can also be used to retrieve the current name and session id as a string suitable for adding to URLs.
I think the problem must be due to a bug in my code somewhere. I've created the test script, below, and it works as expected (on the same server):
url-session-test.php
<?php
$page_title = "URL Session Test (v11)";
ini_set("session.use_cookies", 0);
ini_set("session.use_only_cookies", 0);
ini_set("session.use_trans_sid", 1);
//ini_set("session.cache_limiter", "");
ini_set('session.gc_maxlifetime', 30 * 60); // expires in 30 minutes
session_start();
$session_id = session_id();
$is_new_session = !isset($_SESSION["existing"]);
$_SESSION["existing"] = true;
if ($is_new_session) {
$_SESSION["my_key"] = "MY PRIVATE KEY";
}
$my_session_key = $_SESSION["my_key"];
$timezone = $_SESSION["timezone"];
if ($timezone) {
date_default_timezone_set($timezone);
}
if ($_POST['PHPSESSID']) {
$session_id_received = $_POST['PHPSESSID'];
}
else {
$session_id_received = "";
}
?><!DOCTYPE html>
<html>
<head>
<title><?php echo $page_title; ?></title>
</head>
<body>
<h1><?php echo $page_title; ?></h1>
<p>Is new session: <?php echo $is_new_session; ?></p>
<p>My session key: <?php echo $my_session_key; ?></p>
<p>Received session ID: <?php echo $session_id_received; ?></p>
<p>Actual session ID: <?php echo $session_id; ?></p>
<form method="POST">
<input type="submit" value="Click this form submit button to see how if the above session ID is received by the next page" />
</form>
<a href="url-session-test.php">Hover over this link to check the session ID parameter</a>
</body>
</html>
Will post the actual bug once I've found it...
UPDATE
The problem was that I was using a POST-Redirect-GET model and I was not appending the required PHPSESSID
parameter to the GET url!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With