Skip to content

fix(core): keep encrypted session slots readable across key drift (imp #66)#174

Merged
ralflang merged 1 commit into
FRAMEWORK_6_0from
fix/imp-66-padding-error
Jun 26, 2026
Merged

fix(core): keep encrypted session slots readable across key drift (imp #66)#174
ralflang merged 1 commit into
FRAMEWORK_6_0from
fix/imp-66-padding-error

Conversation

@ralflang

Copy link
Copy Markdown
Member

Summary

Fixes the "Invalid PKCS#7 padding byte" fatal that surfaces during portal render when an encrypted session slot's per-session key has drifted from the ciphertext it protects (cookie eviction, session-id rotation without re-encrypt, upgrade boundary).

Four layered changes in one commit:

  1. HordeSession::getEncrypted catches decrypt failures and returns null instead of letting the throwable escape. AuthCredentialStore::get already turns null into false, so consumers degrade gracefully.
  2. Horde_Core_Alarm_Handler_Mail (new, extends Horde_Alarm_Handler directly) defers Horde_Mail resolution to the first notify() call. Removes the eager IMAP-credential dereference from every portal render that touches the alarm notifier decorator.
  3. SessionLifecycle::regenerate() drains plaintexts under the old key, calls session_regenerate_id(true) + secret->setKey(), re-encrypts under the new key. A new HordeSession::reEncryptAll(\Closure $rotate) packages the drain/rotate/refill sequence; slots that fail to decrypt under the current key are dropped from both the data and the encryption map.
  4. Horde_Core_Secret_Cbc now persists the per-session key in the session payload ($_SESSION['_secret']['key']) via a new SessionSecret::setSession() wiring point on HordeSessionFactory::create(). Migrates the value from the legacy horde_secret_key cookie on first read; cookie continues to be written for BC. This removes the cookie-only dependency that made the bug reproducible in the wild.

Threat-model note: collocating the key with the ciphertext is a deliberate trade. The split-trust property (an attacker with only the session row gets useless bytes) is restored by a follow-up HKDF design filed under ~/php/horde-development/libraries/core/session-encryption-hkdf-strategy-2026-06-25.md.

Related: horde/imp#66, horde/imp#72.

@ralflang ralflang marked this pull request as draft June 25, 2026 20:26
@ralflang ralflang marked this pull request as ready for review June 26, 2026 03:47
@ralflang ralflang merged commit 297cc04 into FRAMEWORK_6_0 Jun 26, 2026
0 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant