Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ All notable changes to **Tiger Core** (`webtigers/tiger-core`). Format follows

## [Unreleased]

## [1.8.3] — 2026-09-16

### Fixed

- **A stale session cookie 500'd the site under the DB session handler too** (1.8.2 covered only the
files handler). The real cause is broader: cPanel leaves PHP's `session.use_strict_mode` off, so a
client-supplied unknown session id is accepted as-is — the files handler then reads a foreign,
unreadable file, and either handler can leave a phantom id that a later `regenerateId()` rejects.
The bootstrap now enables `session.use_strict_mode` before starting (PHP mints a fresh id for any
unknown one, the standard defence), keeps the unreadable-files guard as a belt, and retries once
with a clean id if start still throws — so a returning visitor with any stale cookie is a guest,
never a 500. Verified on a live cPanel install under both the DB and files handlers (TIGER-138).

## [1.8.2] — 2026-09-16

### Fixed
Expand Down
21 changes: 19 additions & 2 deletions library/Tiger/Application/Bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -662,8 +662,25 @@ protected function _initSession()
}

if (!Zend_Session::isStarted()) {
if (!$useDb) { self::dropUnreadableSessionId(); }
Zend_Session::start();
// A session id the BROWSER still carries can be one this process cannot use: cPanel's shared
// session directory after an account is deleted and recreated (the files handler's file
// belongs to the old uid; every returning visitor to the domain hits it), or any unknown id
// a client presents. Strict mode is the standard defence — PHP rejects an uninitialised id
// and mints a fresh one itself, so nothing reads the foreign file and no phantom id survives
// to trip a later regenerate. cPanel leaves it off; turn it on. (Belt: drop a provably
// unreadable files id too, for a SAPI where strict mode is disabled outright.)
@ini_set('session.use_strict_mode', '1');
self::dropUnreadableSessionId();
try {
Zend_Session::start();
} catch (Zend_Session_Exception $e) {
// Last resort: forget the presented id entirely and start clean, so a visitor is a guest,
// never a 500. (Regenerate needs an active session, so clear the cookie + reset the id.)
error_log('Tiger session: start failed (' . $e->getMessage() . '); starting a clean session');
if (!headers_sent()) { @setcookie(session_name(), '', ['expires' => 1, 'path' => '/']); }
unset($_COOKIE[session_name()]);
if (session_status() !== PHP_SESSION_ACTIVE) { session_id(bin2hex(random_bytes(16))); Zend_Session::start(); }
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion library/Tiger/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
class Tiger_Version
{
/** Current Tiger Core version. Keep in lockstep with the git tag cut for a release. */
const VERSION = '1.8.2';
const VERSION = '1.8.3';
}
Loading