← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

Weak Session ID

Security CWE-330 OWASP A2:2021 CVSS 8.1 PHP 5.0+ Intermediate
debt(d5/e3/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep and psalm as tools, both specialist SAST tools. The code_pattern targets custom session ID generation using rand(), md5(), or uniqid(), and short session.sid_length in php.ini — these patterns require static analysis to detect and won't be caught by a default linter or compiler.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix is to use PHP's default session handler with session.hash_function=sha256 and session.entropy_length=32, and never generate session IDs manually. This is a configuration change plus replacing custom generation calls — a small targeted fix within one component rather than a single one-liner, but not a multi-file refactor.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The applies_to scope is web context only, and session ID generation is typically handled in one place (session initialization and login flow). Once corrected, the rest of the codebase is largely unaffected. The burden is real but contained to the authentication/session layer.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception field explicitly states that developers assume PHP's built-in session_start() always generates cryptographically secure session IDs, when in fact older PHP versions used weak entropy sources. A competent developer familiar with modern PHP would reasonably assume the built-in is safe, making this a serious trap that contradicts reasonable expectations based on documentation and common belief.

About DEBT scoring →

Also Known As

predictable session ID short session token weak session token

TL;DR

Session identifiers generated with insufficient entropy can be guessed or brute-forced, allowing session hijacking.

Explanation

A weak session ID is one that is too short, uses a predictable algorithm (sequential numbers, MD5 of timestamp), or is derived from guessable input. Attackers can enumerate or predict valid session tokens to hijack authenticated sessions without needing credentials. PHP's default session ID generator is cryptographically secure when session.use_strict_mode is enabled and the session handler uses random_bytes() internally — avoid custom session ID generation unless you use random_bytes(32) or similar.

Common Misconception

PHP's built-in session_start() always generates cryptographically secure session IDs. Older PHP versions used weak entropy sources. Always verify session.hash_function is set to a strong algorithm and session IDs are sufficiently long (at least 128 bits).

Why It Matters

A short or predictable session ID can be brute-forced or guessed, granting the attacker a valid authenticated session without any credentials.

Common Mistakes

  • Using a custom session ID generation function instead of PHP's session_regenerate_id().
  • Short session IDs (less than 128 bits of entropy) that are feasible to enumerate.
  • Not regenerating the session ID after login — allows session fixation attacks.
  • Including user-supplied values (like user ID) in the session ID, reducing its unpredictability.

Avoid When

  • Never generate session IDs manually using rand(), mt_rand(), uniqid(), or md5(time()).
  • Do not transmit session IDs in URLs — always use HttpOnly, Secure cookies.

When To Use

  • Use PHP's built-in session_start() with session.use_strict_mode=1 — it generates cryptographically secure session IDs automatically.
  • Regenerate the session ID after login with session_regenerate_id(true) to prevent fixation attacks.

Code Examples

✗ Vulnerable
// Predictable session IDs
$sessionId = md5($userId . time()); // time-based, guessable
✓ Fixed
// PHP's session_start() with secure config generates cryptographically
// random session IDs by default (uses /dev/urandom)
ini_set('session.entropy_length', 32);
ini_set('session.hash_function', 'sha256');
ini_set('session.hash_bits_per_character', 6);
// Result: 43+ char session ID from CSPRNG

// For API tokens — random bytes
$token = bin2hex(random_bytes(32)); // 64 char hex token
$stored = hash('sha256', $token);   // store hash in DB, send raw to client

Added 15 Mar 2026
Edited 31 Mar 2026
Views 97
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 1 ping S 0 pings S 0 pings M 1 ping T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 1 ping T 3 pings W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S
Amazonbot 1
No pings yesterday
PetalBot 8 Amazonbot 7 ChatGPT 7 Ahrefs 6 SEMrush 6 Google 4 Scrapy 4 Bing 3 Perplexity 2 Unknown AI 2 Claude 2 Twitter/X 2 Applebot 2 Meta AI 1 Sogou 1 Brave Search 1
crawler 53 crawler_json 5
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
Use PHP's default session handler with session.hash_function=sha256 and session.entropy_length=32; never generate session IDs manually
📦 Applies To
PHP 5.0+ web
🔗 Prerequisites
🔍 Detection Hints
Custom session ID generation using rand() md5() or uniqid(); short session.sid_length in php.ini
Auto-detectable: ✓ Yes semgrep psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✓ Auto-fixable Fix: Low Context: File Tests: Update
CWE-330 CWE-6 CWE-338


✓ schema.org compliant