FIX: Ensure existing session can be accessed if headers_sent()

If a session already exists, and Session::start() isn’t called until
after a large enough block of content is output, then headers_sent()
will be false. The previous code prevented the session from being
started in this case. That might makes sense for the creation of a new
session, but it prevent legitimate access to an existing session.

This mostly manifested when running debugging tools such as showqueries,
which may output content before the session is started.
This commit is contained in:
Sam Minnee 2018-09-19 14:24:40 +12:00
parent 89df5515ae
commit b98c87a6c5

View File

@ -298,11 +298,20 @@ class Session
}
}
if (!session_id() && !headers_sent()) {
if ($domain) {
session_set_cookie_params($timeout, $path, $domain, $secure, true);
// If the session cookie is already set, then the session can be read even if headers_sent() = true
// This helps with edge-case such as debugging.
if (!session_id() && (!headers_sent() || !empty($_COOKIE[ini_get('session.name')]))) {
if (!headers_sent()) {
session_set_cookie_params($timeout, $path, $domain ?: null, $secure, true);
$limiter = $this->config()->get('sessionCacheLimiter');
if (isset($limiter)) {
session_cache_limiter($limiter);
}
// If headers are sent then we can't have a session_cache_limiter otherwise we'll get a warning
} else {
session_set_cookie_params($timeout, $path, null, $secure, true);
session_cache_limiter(null);
}
// Allow storing the session in a non standard location
@ -311,16 +320,13 @@ class Session
}
// If we want a secure cookie for HTTPS, use a seperate session name. This lets us have a
// seperate (less secure) session for non-HTTPS requests
// seperate (less secure) session for non-HTTPS requests. Note that if this causes problems
// if headers_sent() is true then it's best to throw the resulting error rather than risk
// a security hole.
if ($secure) {
session_name($this->config()->get('cookie_name_secure'));
}
$limiter = $this->config()->get('sessionCacheLimiter');
if (isset($limiter)) {
session_cache_limiter($limiter);
}
session_start();
if (isset($_SESSION)) {