Monitor vulnerabilities like this one.
Sign up free to get alerted when software you use is affected.
6.9
Serendipity allows attackers to steal user sessions
GHSA-4m6c-649p-f6gf
CVE-2026-39963
Summary
Serendipity's authentication cookies can be set to target an attacker's website, allowing them to hijack user sessions. This happens when an attacker controls the 'Host' header during login, which can occur through a malicious proxy or other network manipulation. To protect your users, update Serendipity to a fixed version or ensure that your network configuration prevents attackers from manipulating the 'Host' header.
What to do
- Update s9y serendipity to version 2.6.0.
Affected software
| Ecosystem | Vendor | Product | Affected versions |
|---|---|---|---|
| composer | s9y | serendipity |
< 2.6.0 Fix: upgrade to 2.6.0
|
Original title
Serendipity has a Host Header Injection allows authentication cookie scoping to attacker-controlled domain in functions_config.inc.php
Original description
### Summary
The `serendipity_setCookie()` function uses `$_SERVER['HTTP_HOST']` without validation as the `domain` parameter of `setcookie()`. An attacker can force authentication cookies — including session tokens and auto-login tokens — to be scoped to an attacker-controlled domain, facilitating session hijacking.
### Details
In `include/functions_config.inc.php:726`:
```php
function serendipity_setCookie($name, $value, $securebyprot = true, ...) {
$host = $_SERVER['HTTP_HOST']; // ← attacker-controlled, no validation
if ($securebyprot) {
if ($pos = strpos($host, ":")) {
$host = substr($host, 0, $pos); // strips port only
}
}
setcookie("serendipity[$name]", $value, [
'domain' => $host, // ← poisoned domain
'httponly' => $httpOnly,
'samesite' => 'Strict'
]);
}
```
This function is called during login with sensitive cookies:
```php
// functions_config.inc.php:455-498
serendipity_setCookie('author_autologintoken', $rnd, true, false, true);
serendipity_setCookie('author_username', $user);
serendipity_setCookie('author_token', $hash);
```
If an attacker can influence the `Host` header at login time (e.g. via MITM, reverse proxy misconfiguration, or load balancer), authentication cookies are issued scoped to the attacker's domain instead of the legitimate one.
### PoC
```bash
curl -v -X POST \
-H "Host: attacker.com" \
-d "serendipity[user]=admin&serendipity[pass]=admin" \
http://[TARGET]/serendipity_admin.php 2>&1 | grep -i "set-cookie"
```
Expected output:
```http
Set-Cookie: serendipity[author_token]=; domain=attacker.com; HttpOnly
```
### Impact
- **Session fixation** — attacker pre-sets a cookie scoped to their domain, then tricks the victim into authenticating, inheriting the poisoned token
- **Token leakage** — `author_autologintoken` scoped to wrong domain may be sent to attacker-controlled infrastructure
- **Privilege escalation** — if admin logs in under a poisoned Host header, their admin token is compromised
### Suggested Fix
Validate `HTTP_HOST` against the configured `$serendipity['url']` before use:
```php
function serendipity_setCookie($name, $value, ...) {
global $serendipity;
$configured = parse_url($serendipity['url'], PHP_URL_HOST);
$host = preg_replace('/:[0-9]+$/', '', $_SERVER['HTTP_HOST']);
$host = ($host === $configured) ? $host : $configured;
setcookie("serendipity[$name]", $value, [
'domain' => $host,
...
]);
}
```
The `serendipity_setCookie()` function uses `$_SERVER['HTTP_HOST']` without validation as the `domain` parameter of `setcookie()`. An attacker can force authentication cookies — including session tokens and auto-login tokens — to be scoped to an attacker-controlled domain, facilitating session hijacking.
### Details
In `include/functions_config.inc.php:726`:
```php
function serendipity_setCookie($name, $value, $securebyprot = true, ...) {
$host = $_SERVER['HTTP_HOST']; // ← attacker-controlled, no validation
if ($securebyprot) {
if ($pos = strpos($host, ":")) {
$host = substr($host, 0, $pos); // strips port only
}
}
setcookie("serendipity[$name]", $value, [
'domain' => $host, // ← poisoned domain
'httponly' => $httpOnly,
'samesite' => 'Strict'
]);
}
```
This function is called during login with sensitive cookies:
```php
// functions_config.inc.php:455-498
serendipity_setCookie('author_autologintoken', $rnd, true, false, true);
serendipity_setCookie('author_username', $user);
serendipity_setCookie('author_token', $hash);
```
If an attacker can influence the `Host` header at login time (e.g. via MITM, reverse proxy misconfiguration, or load balancer), authentication cookies are issued scoped to the attacker's domain instead of the legitimate one.
### PoC
```bash
curl -v -X POST \
-H "Host: attacker.com" \
-d "serendipity[user]=admin&serendipity[pass]=admin" \
http://[TARGET]/serendipity_admin.php 2>&1 | grep -i "set-cookie"
```
Expected output:
```http
Set-Cookie: serendipity[author_token]=; domain=attacker.com; HttpOnly
```
### Impact
- **Session fixation** — attacker pre-sets a cookie scoped to their domain, then tricks the victim into authenticating, inheriting the poisoned token
- **Token leakage** — `author_autologintoken` scoped to wrong domain may be sent to attacker-controlled infrastructure
- **Privilege escalation** — if admin logs in under a poisoned Host header, their admin token is compromised
### Suggested Fix
Validate `HTTP_HOST` against the configured `$serendipity['url']` before use:
```php
function serendipity_setCookie($name, $value, ...) {
global $serendipity;
$configured = parse_url($serendipity['url'], PHP_URL_HOST);
$host = preg_replace('/:[0-9]+$/', '', $_SERVER['HTTP_HOST']);
$host = ($host === $configured) ? $host : $configured;
setcookie("serendipity[$name]", $value, [
'domain' => $host,
...
]);
}
```
ghsa CVSS3.1
6.9
Vulnerability type
CWE-565
Published: 14 Apr 2026 · Updated: 15 Apr 2026 · First seen: 14 Apr 2026