CVE-2026-84308 Overview
CVE-2026-84308 is a timing side-channel vulnerability in phpseclib, a widely deployed PHP secure communications library. The flaw affects pure-PHP X25519 scalar multiplication in versions prior to 3.0.57 and 4.0.1. The add() and subtract() methods in phpseclib/Math/PrimeField/Integer.php perform data-dependent conditional modular reductions. During the Montgomery ladder, these reductions leak information about the secret scalar through per-step timing and libgmp call-count observations. A local observer can recover a reused 251-bit clamped private key. The issue is tracked under CWE-208: Observable Timing Discrepancy.
Critical Impact
Recovery of a reused X25519 private scalar permanently compromises all operations using that key, including decryption and authentication.
Affected Products
- phpseclib versions prior to 3.0.57
- phpseclib versions prior to 4.0.1
- PHP applications using X25519 with reused static keys via the pure-PHP path (no ext-sodium)
Discovery Timeline
- 2026-09-01 - CVE-2026-84308 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-84308
Vulnerability Analysis
The vulnerability resides in the pure-PHP implementation of X25519 scalar multiplication used by phpseclib when the native sodium extension is unavailable. The add() and subtract() routines in phpseclib/Math/PrimeField/Integer.php conditionally perform modular reduction based on operand values. Because operand magnitudes during a Montgomery ladder step depend on the secret scalar bit being processed, the reduction path taken varies per iteration. This produces observable differences in execution time and in the number of calls made to libgmp entry points. An attacker who can measure these signals across many ladder executions can reconstruct bits of the private scalar. The classification of Observable Timing Discrepancy [CWE-208] applies directly.
Root Cause
The root cause is a lack of constant-time arithmetic in phpseclib/Math/PrimeField/Integer.php. Both add() and subtract() branch on secret-dependent operand size, violating the constant-time requirement for cryptographic scalar multiplication. The derivation path in phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php invokes the pure-PHP multiplication without a native-engine check. The PKCS8 loader at phpseclib/Crypt/EC/Formats/Keys/PKCS8.php reaches the vulnerable code when ext-sodium is not installed.
Attack Vector
Exploitation requires local observation capability and specific preconditions. The attacker must know the corresponding public key, the private key must be reused or long-lived, and the pure-PHP path must execute. The observer must resolve individual ladder steps or libgmp entry-point calls. Ephemeral X25519 keys, including those used by phpseclib's normal SSH key exchange, are not affected because a single-use scalar provides insufficient data for statistical recovery.
// Patch excerpt: phpseclib/Crypt/EC/Formats/Keys/Common.php
namespace phpseclib3\Crypt\EC\Formats\Keys;
use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\EC;
use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve;
use phpseclib3\Crypt\EC\BaseCurves\Binary as BinaryCurve;
use phpseclib3\Crypt\EC\BaseCurves\Montgomery;
use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
use phpseclib3\Crypt\EC\Curves\Curve25519;
use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\UnsupportedCurveException;
Source: GitHub Commit fb56bc5
Detection Methods for CVE-2026-84308
Indicators of Compromise
- Repeated invocation of phpseclib3\Crypt\EC\Formats\Keys\MontgomeryPrivate::load against the same static X25519 keypair from a co-located process.
- Presence of local profiling or timing tools (e.g., strace, ltrace, perf) accessing the PHP worker process while X25519 operations occur.
- Absence of the PHP sodium extension (ext-sodium) in phpinfo() output on hosts performing X25519 with static keys.
Detection Strategies
- Inventory PHP applications using phpseclib and identify those loading static X25519 private keys via Crypt\EC\PKCS8 or MontgomeryPrivate loaders.
- Audit runtime environments for extension_loaded('sodium') returning false, which forces the vulnerable pure-PHP path.
- Correlate process-tracing tool execution with cryptographic worker activity on shared hosts.
Monitoring Recommendations
- Enable process-level auditing (auditd or equivalent) to flag ptrace, perf_event_open, or /proc/[pid]/ reads targeting PHP workers.
- Log phpseclib version metadata during application startup and alert on versions below 3.0.57 or 4.0.1.
- Monitor shared-tenant hosts for unexpected local users executing timing measurement tooling near cryptographic services.
How to Mitigate CVE-2026-84308
Immediate Actions Required
- Upgrade phpseclib to version 3.0.57 or 4.0.1 across all dependent applications and vendored copies.
- Install and enable the PHP ext-sodium extension so X25519 operations use the native constant-time implementation.
- Rotate any long-lived or reused X25519 private keys that were loaded on hosts running the vulnerable code path.
Patch Information
The fix is available in phpseclib 3.0.57 and phpseclib 4.0.1. The remediation is documented in commit fb56bc5 and advisory GHSA-q97c-8qh3-fpc6. The patch introduces a native-engine check in MontgomeryPrivate and routes X25519 through the sodium extension when available.
Workarounds
- Install ext-sodium to bypass the vulnerable pure-PHP code path until an upgrade is scheduled.
- Avoid reusing static X25519 keys; use ephemeral scalars where the protocol permits.
- Restrict local shell access on hosts performing X25519 operations to prevent timing observations.
# Verify sodium extension is loaded and upgrade phpseclib
php -m | grep -i sodium
composer require phpseclib/phpseclib:^3.0.57
# Or for the 4.x branch
composer require phpseclib/phpseclib:^4.0.1
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.