fix: CSRF flow ships the raw token, not the HMAC cookie
This commit is contained in:
+22
-1
@@ -44,9 +44,15 @@ if ($secret === false || $secret === '') {
|
||||
}
|
||||
|
||||
// 2. Ensure the __csrf cookie is set. If absent, issue a fresh token.
|
||||
// The double-submit pattern stores the raw token in a separate readable
|
||||
// cookie so client code (meta tag, JS) can echo it back as the
|
||||
// X-CSRF-Token header. The HMAC cookie is the verification oracle;
|
||||
// the raw-token cookie rides parallel and is readable by document.cookie
|
||||
// or the equivalent server-side read.
|
||||
$cookies = $_COOKIE;
|
||||
$existingCookie = (string) ($cookies['__csrf'] ?? '');
|
||||
if ($existingCookie === '') {
|
||||
$existingRawToken = (string) ($cookies['__csrf_token'] ?? '');
|
||||
if ($existingCookie === '' || $existingRawToken === '') {
|
||||
[$token, $cookie] = CsrfToken::issue($secret);
|
||||
setcookie('__csrf', $cookie, [
|
||||
'expires' => time() + 86400,
|
||||
@@ -55,8 +61,23 @@ if ($existingCookie === '') {
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax',
|
||||
]);
|
||||
// The raw token rides in a readable cookie so server-side templates
|
||||
// can echo it into the <meta name="csrf-token"> tag without keeping
|
||||
// the raw token in `index.php` per-request state. HttpOnly off so the
|
||||
// server can read it via the request cookie jar; security comes from
|
||||
// the HMAC verification, not from hiding the raw token (which the
|
||||
// browser would already see in the meta tag anyway).
|
||||
setcookie('__csrf_token', $token, [
|
||||
'expires' => time() + 86400,
|
||||
'path' => '/',
|
||||
'secure' => isset($_SERVER['HTTPS']),
|
||||
'httponly' => false,
|
||||
'samesite' => 'Lax',
|
||||
]);
|
||||
$existingCookie = $cookie;
|
||||
$existingRawToken = $token;
|
||||
$cookies['__csrf'] = $cookie;
|
||||
$cookies['__csrf_token'] = $token;
|
||||
}
|
||||
|
||||
// 3. Compute the upload-endpoint user token (derived from the same secret).
|
||||
|
||||
Reference in New Issue
Block a user