← Back to Feed CACHED · 2026-06-29 11:17:12 · CACHE_KEY CVE-2026-3256
CVE-2026-3256 · CWE-338 · Disclosed 2026-03-28

HTTP::Session versions before 0

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A Perl session library was seeding SHA-1 with `rand()`, epoch time, and PID — none of which are secrets

HTTP::Session (Ktat's CPAN module) before 0.54 uses HTTP::Session::ID::SHA1 by default, which builds session identifiers by SHA-1-hashing the output of Perl's non-cryptographic rand(), the high-resolution epoch time, and the process ID. None of those inputs are unpredictable to a remote attacker: rand() is a deterministic LCG seeded once at interpreter start, epoch time leaks via the Date: response header, and PIDs live in a tiny space (typically <65k on Linux, <99k on modern kernels). The sibling HTTP::Session::ID::MD5 has the same defect. Affected: all versions before 0.54. Fixed: 0.54 (uses Crypt::URandom / /dev/urandom).

Vendor severity is *wrong*. The 9.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H is auto-generated boilerplate that ignores attacker work factor and victim selection. To exploit this, an attacker has to: identify a *target* session (a specific authenticated user), know roughly when they logged in, know or brute-force the worker PID that minted the ID, and replay enough requests to find the surviving rand() seed. AC:L is indefensible — this is AC:H at best. Real-world impact is *session hijack of a specific user under heavy preconditions*, not unauthenticated RCE.

"Vendor's 9.8 is fantasy math. Predictable session IDs are real but require burning massive compute to guess timing + PID + rand() state."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify a target running vulnerable HTTP::Session

Attacker fingerprints a Perl web app — typically Plack/PSGI, Catalyst, or Mojolicious-on-PSGI deployments — and confirms session cookies match the SHA-1 hex length and structure produced by HTTP::Session::ID::SHA1. CPAN downloads for HTTP::Session are low-volume (sub-1k/month) so the addressable population is small.
Conditions required:
  • Public-facing Perl web app
  • Application uses HTTP::Session (not HTTP::Session2, Plack::Session, Catalyst::Plugin::Session, Dancer Session, or Mojolicious::Sessions)
Where this breaks in practice:
  • HTTP::Session is a niche, low-uptake CPAN module — most Perl shops use Plack::Session or framework-native sessions
  • Cookie name is app-defined; no reliable banner
Detection/coverage: No mainstream scanner signature; manual cookie-entropy testing or SBOM inspection of cpanfile/Makefile.PL is required.
STEP 02

Harvest server-side state to narrow the seed space

Attacker pulls the Date: header to anchor epoch time within a few seconds, requests static endpoints repeatedly to estimate worker PID ranges (via fork patterns under prefork MPMs), and may chain a separate info-leak to read /proc/self/status or error pages that disclose PID. Each of these narrows the SHA-1 preimage search space.
Conditions required:
  • Server returns Date header (default)
  • Stable PID range observable, or PID leak available
Where this breaks in practice:
  • Behind a CDN or reverse proxy that strips/normalizes Date and rewrites error pages, PID is invisible
  • Modern PID randomization (kernel.randomize_va_space, large pid_max) inflates the search space
Detection/coverage: WAFs do not flag this; only anomalous request volume to static endpoints might trip rate-limit telemetry.
STEP 03

Brute-force session ID space against the target's session window

With epoch±N seconds, PID candidate set, and the assumption that rand() has only the default time-based seed, the attacker enumerates SHA-1(rand_state ‖ epoch ‖ pid) and replays each as a session cookie until one authenticates. The work factor is ~2^30–2^40 hashes per *targeted minute*, dwarfed if rand() is reseeded or if the app calls srand with additional entropy.
Conditions required:
  • Target user is actively logged in during the guessing window
  • Server does not bind sessions to IP or User-Agent
  • No anti-automation on the protected endpoint
Where this breaks in practice:
  • Even modest request-rate limiting per source IP makes online brute force impractical
  • If the app calls srand post-fork with extra entropy (common in Plack workers), the keyspace explodes
  • Bot-management / WAF anomaly rules trigger on millions of failed cookie replays
Detection/coverage: Massive 401/302 spikes against a single endpoint are trivially detectable in any SIEM with auth telemetry.
STEP 04

Session hijack — single user impact

On a successful guess, the attacker rides the victim's session at whatever privilege level that user holds. Impact is bounded by that one account; no privilege escalation, no lateral movement primitive provided by the bug itself.
Conditions required:
  • Compromised session belongs to a high-value user for the impact to matter
Where this breaks in practice:
  • Step-up auth / MFA reprompt on sensitive actions blunts post-hijack damage
  • Short session TTLs limit the value of any single guess
Detection/coverage: Impossible-travel and concurrent-session detections (Okta, Azure AD risk, Splunk UEBA) catch the post-hijack ride.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed. No public exploitation reports, no honeypot hits, no incident-response writeups referencing this CVE.
Public PoCNo weaponized PoC on GitHub or Exploit-DB. The oss-security thread for the sibling CVE-2026-3255 (HTTP::Session2) describes the methodology but stops short of a turnkey exploit.
EPSS0.53% (0.0053) — below the 50th percentile. EPSS agrees this is not a near-term exploitation target.
KEV statusNot listed by CISA, and unlikely to be added — no ransomware operator is going to brute-force SHA-1 preimages for niche Perl modules.
CVSS vector (vendor)CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8. AC:L is wrong — exploitation requires guessing rand() state + PID + epoch. Realistic vector is closer to AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N ≈ 5.9.
Affected versionsHTTP::Session < 0.54 on CPAN (Ktat distribution). Sibling defect in HTTP::Session2 < 1.12 is tracked as CVE-2026-3255.
Fixed versionsHTTP::Session 0.54+, switching default ID generator to Crypt::URandom / /dev/urandom. No major distro backports — this is a CPAN-only fix.
Exposure dataNo Shodan/Censys fingerprint exists for HTTP::Session specifically — it's identifiable only by cookie shape. Monthly CPAN download counts are in the low hundreds; estimated installed base is small four digits globally.
DisclosureReported via oss-security on 2026-02-27 alongside CVE-2026-3255 (HTTP::Session2) and adjacent Mojolicious/Concierge session-ID CVEs; this CVE assigned 2026-03-28.
ReporterDisclosed by the MetaCPAN Security WG / oss-security contributors auditing the CPAN session-module ecosystem; same class of finding as CVE-2026-2439 (Concierge::Sessions) and CVE-2026-9692 (Mojolicious::Sessions::Storable).
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.3/10)

Downgraded from CRITICAL 9.8 to MEDIUM 5.3 because the *single most decisive factor* is attacker work factor: exploitation requires brute-forcing rand() state, PID, and epoch timing during a live session window, which is incompatible with the vendor's AC:L assumption. Blast radius is also bounded to a single user's session — there is no role-multiplier path to fleet, identity, or supply-chain compromise from the bug itself.

HIGH technical analysis of the weak-RNG defect
HIGH vendor severity is overstated
MEDIUM installed-base estimate (CPAN telemetry is partial)
LOW future EPSS movement if a turnkey PoC drops

Why this verdict

  • Work factor crushes AC:L. Vendor scored AC:L, but the real chain requires aligning rand() state, PID, and epoch within a few seconds for a *targeted* user — that is textbook AC:H, dropping the score by ~3 points alone.
  • Impact is single-session, not system-wide. A successful hijack rides one user's privileges; there is no integrity write outside that user's app context and no availability impact. I:H/A:H in the vendor vector is not defensible.
  • Installed base is tiny. HTTP::Session is a niche CPAN module — most Perl web apps use Plack::Session, Catalyst::Plugin::Session, Dancer::Session, or Mojolicious::Sessions. Estimated global installs are low four digits.
  • No exploitation pressure. EPSS 0.53%, not KEV, no PoC weaponization, no campaign signal. The bar to even *attempt* this against a real target dwarfs the bar to phish credentials.
  • Role multiplier: low-value role (app session store). Even on a high-value app (banking portal, admin console), the chain delivers *one* user's session. The affected component is not in the identity/PKI/hypervisor/backup/CA/kernel-agent catalog — no fleet, domain, or supply-chain pivot is provided by the bug itself.
  • Role multiplier: typical role (line-of-business Perl web app). Same — impact terminates at one hijacked session per successful brute-force window. Defense-in-depth (MFA, IP binding, short TTLs) further blunts the outcome.
  • Role multiplier: high-value role. N/A — HTTP::Session is not deployed as identity-plane infrastructure. There is no canonical high-value-role deployment of this component, so the deployment-role floor does not lift the verdict above HIGH.

Why not higher?

Not HIGH because exploitation requires sustained, noisy brute-force aligned with a live victim session — detectable by trivial rate-limiting or SIEM auth-failure alerting — and the addressable installed base is small four-digit globally. There is no role-multiplier path: the bug does not live in identity, PKI, hypervisor, backup, or kernel-agent code.

Why not lower?

Not LOW because the defect is real and exploitable in principle: an attacker with a separate PID/timing info-leak and a high-value target sitting behind a misconfigured proxy can succeed, and session hijack of a privileged user (admin, finance, healthcare clinician) is a non-trivial breach event. Upgrade to 0.54 is cheap, so leaving it on the backlog indefinitely is wrong.

05 · Compensating Control

What to do — in priority order.

  1. Force HTTP::Session::ID::Generator to a CSPRNG-backed implementation — Override the default by passing id_generator => HTTP::Session::ID::SHA1->new(rand_bits => sub { Crypt::URandom::urandom(32) }) or swap in a custom generator that reads /dev/urandom directly. This neutralizes the predictable-seed defect without waiting for the package upgrade. No mitigation SLA at MEDIUM — but if a high-value app is affected, ship this within 30 days.
  2. Bind sessions to client IP and User-Agent fingerprint — Even with a guessed cookie value, the attacker also has to spoof the originating client fingerprint. Implement in the PSGI middleware layer; rejects mismatched sessions before the handler runs.
  3. Cut session TTL and rotate cookie on privilege change — Short TTL (≤30 min idle, ≤8h absolute) shrinks the brute-force window. Rotating session IDs after login and after any role escalation invalidates pre-hijack guessing work.
  4. Rate-limit cookie replay on auth-bearing endpoints — Any single source IP submitting hundreds of distinct session cookies per minute is unambiguously hostile — block at the reverse proxy (nginx limit_req, HAProxy stick-tables) or the WAF.
  5. Strip the Date: header at the edge and suppress PID leaks — Cuts off two of the three seed inputs an attacker needs. Configure your reverse proxy to overwrite Date: and ensure error pages don't leak $$ or /proc paths.
What doesn't work
  • Secure and HttpOnly cookie flags — they prevent XSS theft, but this bug lets an attacker *predict* the cookie without ever touching the browser.
  • WAF signature rules — there is no payload pattern; brute-forced cookies look exactly like legitimate ones.
  • TLS / HSTS — the cookie value is predictable from server-side state, not intercepted on the wire.
  • MFA on login — once a session cookie is hijacked, the attacker is *past* the login MFA prompt. Only step-up MFA on sensitive actions helps.
06 · Verification

Crowdsourced verification payload.

Run on each Perl application host as the user that owns the app's lib path (or root). Invoke as ./check-cve-2026-3256.sh /path/to/app/lib — the script walks installed HTTP::Session modules and checks their $VERSION. Requires read access to the Perl @INC directories.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate verification — CVE-2026-3256 (HTTP::Session < 0.54 weak session IDs)
# Usage: ./check-cve-2026-3256.sh [extra_lib_path ...]
set -u

FIXED_VERSION="0.54"
status="UNKNOWN"
found_any=0

if ! command -v perl >/dev/null 2>&1; then
  echo "UNKNOWN: perl not installed on this host"
  exit 2
fi

# Build -I args for any extra lib paths supplied (e.g. local::lib, Carton, app vendor dirs)
INC_ARGS=()
for p in "$@"; do
  [ -d "$p" ] && INC_ARGS+=("-I$p")
done

result=$(perl "${INC_ARGS[@]}" -e '
  use strict; use warnings;
  my $fixed = "0.54";
  my $worst = "PATCHED";
  eval { require HTTP::Session };
  if ($@) { print "NOT_INSTALLED\n"; exit 0; }
  my $v = $HTTP::Session::VERSION // "unknown";
  print "FOUND HTTP::Session $v\n";
  if ($v eq "unknown") { print "STATUS UNKNOWN\n"; exit 0; }
  # numeric compare on dotted/decimal CPAN versions
  require version;
  my $have = version->parse($v);
  my $need = version->parse($fixed);
  if ($have < $need) { print "STATUS VULNERABLE\n"; }
  else { print "STATUS PATCHED\n"; }
' 2>&1)

echo "$result"

if echo "$result" | grep -q "NOT_INSTALLED"; then
  echo "PATCHED: HTTP::Session is not installed in @INC"
  exit 0
fi
if echo "$result" | grep -q "STATUS VULNERABLE"; then
  echo "VULNERABLE: upgrade HTTP::Session to >= ${FIXED_VERSION} (cpanm HTTP::Session~'>=0.54')"
  exit 1
fi
if echo "$result" | grep -q "STATUS PATCHED"; then
  echo "PATCHED: HTTP::Session is at or above ${FIXED_VERSION}"
  exit 0
fi
echo "UNKNOWN: could not determine HTTP::Session version"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Per the noisgate mitigation SLA, MEDIUM carries no mitigation deadline — but if you run a high-value Perl web app on HTTP::Session, deploy the CSPRNG generator override and IP/UA session binding within 30 days as defense-in-depth. For full remediation, upgrade CPAN dependencies to HTTP::Session >= 0.54 within the noisgate remediation SLA of 365 days, ideally rolled into your next quarterly dependency refresh (cpanm HTTP::Session~'>=0.54' or pin in cpanfile). Don't lose sleep over this one — but don't pretend the vendor's 9.8 means it should jump the queue ahead of your actual unauthenticated-RCE backlog. Run the verification script across every Perl host, file results in your SBOM, and move on.

Sources

  1. oss-security disclosure thread (sibling CVE-2026-3255, same defect class)
  2. SentinelOne vulnerability entry — CVE-2026-3256
  3. OffSeq threat radar — CVE-2026-3256
  4. Tenable CVE record
  5. CWE-338 — Use of Cryptographically Weak PRNG
  6. HTTP::Session on MetaCPAN
  7. Crypt::URandom — the right way to do this on Perl
  8. PerlMonks — session id generation guidance
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.