fix(security): require CSRF token for headerless GET JSON actions

ba3741080a
This commit is contained in:
the-djmaze 2026-11-02 01:07:33 +01:00
parent 2de4ebac54
commit 71d10f8cf6

View file

@ -103,11 +103,17 @@ class ServiceActions
$this->oActions->logWrite("{$_SERVER['HTTP_X_SM_TOKEN']} !== {$token} for {$sEmail}", \LOG_ERR, 'Token');
throw new Exceptions\ClientException(Notifications::InvalidToken, null, 'HTTP Token mismatch');
}
} else if ($this->oHttp->IsPost()) {
if (empty($_POST['XToken']) || $_POST['XToken'] !== $token) {
} else {
// A state-changing action must never be triggerable by a bare
// headerless POST/GET (e.g. <img src> or a top-level navigation):
// without the X-SM-Token header the token has to arrive as a
// query parameter. The first-party UI always sends the header,
// so this only affects headerless callers.
$xToken = $this->oHttp->IsPost() ? ($_POST['XToken'] ?? '') : ($_GET['XToken'] ?? '');
if (empty($xToken) || $xToken !== $token) {
$oAccount = $this->oActions->getAccountFromToken(false);
$sEmail = $oAccount ? $oAccount->Email() : 'guest';
$this->oActions->logWrite("{$_POST['XToken']} !== {$token} for {$sEmail}", \LOG_ERR, 'XToken');
$this->oActions->logWrite("{$xToken} !== {$token} for {$sEmail}", \LOG_ERR, 'XToken');
throw new Exceptions\ClientException(Notifications::InvalidToken, null, 'XToken mismatch');
}
}