From 2db141efc668b3aab0ce7c6ed36254ac3d8d94e8 Mon Sep 17 00:00:00 2001 From: Keith Solomon Date: Sun, 26 Jul 2026 11:44:51 -0500 Subject: [PATCH] fix: route the real secret to the action handlers (was reading empty $_SERVER['__csrf_secret']) public/index.php had a line that overwrote the local $secret with $_SERVER['__csrf_secret'] ?? '' just before constructing the four match-action handler closures. The synthetic key is only written to the request's $server array (line 105), not to the global $_SERVER superglobal, so the read always returned ''. The handlers were constructed with an empty secret, TurnToken::verify then HMAC'd the supplied token against '' which never matched the token that PostStartMatch had minted with the real (32-byte) secret, and every action returned 409 {error: turn}. Fix: delete the line that re-reads $secret; the closures now use the outer $secret (read from var/secret.key or BATTLEFORGE_SECRET at script start). --- public/index.php | 1 - 1 file changed, 1 deletion(-) diff --git a/public/index.php b/public/index.php index 7167f4a..4a5b104 100644 --- a/public/index.php +++ b/public/index.php @@ -152,7 +152,6 @@ $getBundledOne = static function (Request $r, array $p) use ($scenariosDir): Res return (new GetBundledScenario($scenariosDir))->handle($r, $p); }; $getMatchView = static fn (Request $r, array $p): Response => (new GetMatchView())->handle($r, $p); -$secret = (string) ($_SERVER['__csrf_secret'] ?? ''); $postMatchMove = static function (Request $r, array $p) use ($secret): Response { return (new PostMatchMove($secret))->handle($r, $p); };