
CVE-2025-11262 को पुनरुत्पन्न करने के लिए डॉकर लैब, जो Link Whisper Free WordPress प्लगइन में एक अनऑथेंटिकेटेड ಸ्टोर्ड ब्लाइंड XSS है। इसमें कमजोर और पैच किए गए लक्ष्य, PoC स्क्रिप्ट और मूल कारण विश्लेषण शामिल हैं।
इस रिपॉजिटरी में CVE-2025-11262 के पुनरुत्पादन के लिए एक स्थानीय Docker लैब शामिल है, जो WordPress प्लगइन Link Whisper Free को प्रभावित करने वाली एक बिना प्रमाणीकरण के संग्रहीत क्रॉस-साइट स्क्रिप्टिंग समस्या है।
लैब दो प्लगइन संस्करणों की तुलना करती है:
| सेवा | प्लगइन संस्करण | उद्देश्य | URL |
|---|---|---|---|
vuln | 0.9.0 | असुरक्षित लक्ष्य | http://127.0.0.1:8081 |
patched | 0.9.1 | पैच किया गया तुलनात्मक लक्ष्य | http://127.0.0.1:8082 |
प्रदर्शित भेद्यता श्रृंखला इस प्रकार है:
Unauthenticated REST request
→ attacker-controlled user_id is persisted
→ a privileged WordPress user opens the Link Whisper AI Subscription page
→ the stored value is rendered into an admin JavaScript context
→ alert("CVE-2025-11262-LAB") executes on the vulnerable version
हमलावर को संग्रहीत पेलोड लगाने के लिए लॉग इन करने की आवश्यकता नहीं है। JavaScript बाद में तब निष्पादित होती है जब कोई विशेषाधिकार प्राप्त WordPress उपयोगकर्ता प्रभावित व्यवस्थापक पृष्ठ खोलता है।
यह लैब केवल नियंत्रित स्थानीय अनुसंधान, स्रोत-स्तरीय समझ और पोर्टफोलियो प्रदर्शन के लिए डिज़ाइन की गई है।
| दावा | साक्ष्य | इस लैब में कैसे सत्यापित करें |
|---|---|---|
Link Whisper Free 0.9.0 असुरक्षित है। | सार्वजनिक सलाहकार पत्र Link Whisper Free के 0.9.0 तक के संस्करणों को प्रभावित बताते हैं। | PoC को http://127.0.0.1:8081 पर चलाएँ और मुद्रित व्यवस्थापक URL खोलें। |
Link Whisper Free 0.9.1 में फिक्स शामिल है। | सार्वजनिक सलाहकार और चेंजलॉग डेटा 0.9.1 को पैच किए गए संस्करण के रूप में पहचानते हैं। | उसी PoC को http://127.0.0.1:8082 पर चलाएँ; कोई अलर्ट दिखाई नहीं देना चाहिए। |
| पेलोड लगाना बिना प्रमाणीकरण के है। | PoC बिना WordPress कुकीज़, लॉगिन या nonce के POST अनुरोध भेजता है। | poc/poc.py का निरीक्षण करें; इसे केवल --url की आवश्यकता है। |
| दृश्य प्रभाव WordPress व्यवस्थापक क्षेत्र में ट्रिगर होता है। | जब कोई विशेषाधिकार प्राप्त उपयोगकर्ता Link Whisper AI Subscription पृष्ठ खोलता है, तो संग्रहीत मान प्रस्तुत किया जाता है। | PoC चलाने के बाद, व्यवस्थापक के रूप में लॉगिन करें और मुद्रित व्यवस्थापक URL खोलें। |
पैच किया गया लक्ष्य HTTP स्तर पर अभी भी "ok" लौटा सकता है। | स्थानीय परीक्षण में दोनों लक्ष्य "ok" लौटा सकते हैं; सार्थक अंतर यह है कि पेलोड संग्रहीत और निष्पादित होता है या नहीं। | 8081 और 8082 पर ब्राउज़र व्यवहार की तुलना करें। |
นี่คือส่วน Root Cause Summary สำหรับเอาไปแทนใน README ได้เลยครับ เป็น public-safe ไม่พูดถึงไฟล์อย่าง vuln_detail.txt และอิงกับ lab/source ที่คุณใช้ตอนนี้
CVE-2025-11262 Link Whisper Free 0.9.0 में एक संग्रहीत JavaScript इंजेक्शन श्रृंखला के कारण होता है।
समस्या एक एकल लुप्त एस्केपिंग कॉल नहीं है। यह कई असुरक्षित व्यवहारों की एक श्रृंखला है:
Unauthenticated REST endpoint
→ insufficient validation of user_id
→ persistent storage in wpil_ai_access_user_id
→ unsafe rendering into an admin JavaScript context
→ stored XSS when a privileged user opens the AI Subscription page
Link Whisper Free प्लगइन REST नेमस्पेस के अंतर्गत एक AI प्रमाणीकरण REST एंडपॉइंट पंजीकृत करता है:
const REST_SLUG = 'link-whisper';
const AI_AUTH = 'ai-auth';
एंडपॉइंट को POST रूट के रूप में पंजीकृत किया गया है:
register_rest_route(self::REST_SLUG, self::AI_AUTH, [
'methods' => 'POST',
'callback' => [
$this,
'ai_auth_handler'
],
'permission_callback' => "__return_true",
'show_in_index' => false
]);
चूंकि अनुमति कॉलबैक __return_true है, एंडपॉइंट बिना प्रमाणीकरण के पहुंच योग्य है।
लैब में, प्रभावी एंडपॉइंट है:
/wp-json/link-whisper/ai-auth
इसका मतलब है कि एक बिना प्रमाणीकरण वाला हमलावर WordPress सत्र, nonce या व्यवस्थापक खाते के बिना एंडपॉइंट पर अनुरोध भेज सकता है।
Link Whisper Free 0.9.0 में, हैंडलर REST अनुरोध से हमलावर-नियंत्रित पैरामीटर पढ़ता है:
public function ai_auth_handler( WP_REST_Request $request )
{
if(!empty($request->get_param('access_token'))){
$token = $request->get_param('access_token');
$user_id = $request->get_param('user_id');
$uid = (int)$request->get_param('uid');
$uemail = $request->get_param('uemail');
if(!empty($token) && false !== strpos($token, 'ai-')){
update_option('wpil_ai_access_token', Wpil_Toolbox::encrypt($token));
update_option('wpil_ai_access_user_id', $user_id);
update_option('wpil_ai_access_user_email', $uemail);
update_user_meta($uid, 'wpil_ai_access_user_id', $user_id);
update_user_meta($uid, 'wpil_ai_access_user_email', $uemail);
update_option('wpil_ai_access_authorized', true);
}
return 'ok';
}
return new WP_Error(400, 'Bad request', [ 'status' => 404 ]);
}
असुरक्षित व्यवहार कमजोर सत्यापन शर्त है:
if(!empty($token) && false !== strpos($token, 'ai-')){
यह केवल जाँचता है कि आपूर्ति किए गए एक्सेस टोकन में स्ट्रिंग ai- है या नहीं।
user_id को संग्रहीत करने से पहले कोई सख्त सत्यापन नहीं है:
update_option('wpil_ai_access_user_id', $user_id);
परिणामस्वरूप, हमलावर-नियंत्रित JavaScript को WordPress विकल्प तालिका में संग्रहीत किया जा सकता है।
हमलावर-नियंत्रित user_id मान WordPress विकल्प में संग्रहीत किया जाता है:
wpil_ai_access_user_id
इस लैब में, PoC निम्नलिखित केवल-स्थानीय पेलोड भेजता है:
</script><script>alert("CVE-2025-11262-LAB")</script>
असुरक्षित सेवा पर, पेलोड को wpil_ai_access_user_id के मान के रूप में संग्रहीत किया जाता है।
हमलावर को पेलोड लगाने के लिए लॉग इन करने की आवश्यकता नहीं है। पेलोड बिना प्रमाणीकरण वाले REST एंडपॉइंट के माध्यम से लगाया जाता है।
संग्रहीत मान बाद में प्लगइन सेटिंग्स तर्क के माध्यम से पुनर्प्राप्त किया जाता है:
public static function get_linkwhisper_ai_user_id(){
return get_option('wpil_ai_access_user_id', '');
}
मान को $ai_id को सौंपा जाता है और AI Subscription व्यवस्थापक पृष्ठ पर प्रस्तुत किया जाता है।
Link Whisper Free 0.9.0 में, मान को सीधे एक JavaScript स्ट्रिंग में डाला जाता है:
body: JSON.stringify({
ai_id: "<?php echo $ai_id;?>",
subscription_id: "<?php echo ((!empty($sub)) && isset($sub->subscription_id)) ? $sub->subscription_id: null;?>"
})
चूंकि $ai_id को JavaScript संदर्भ में डालने से पहले एस्केप नहीं किया गया है, एक संग्रहीत पेलोड इच्छित स्ट्रिंग से बाहर निकल सकता है और व्यवस्थापक पृष्ठ खुलने पर JavaScript निष्पादित कर सकता है।
लैब पेलोड के साथ, असुरक्षित प्रस्तुत आउटपुट इसके बराबर हो जाता है:
body: JSON.stringify({
ai_id: "</script><script>alert("CVE-2025-11262-LAB")</script>",
subscription_id: ""
})
ब्राउज़र में, इंजेक्ट किया गया समापन </script> टैग मूल स्क्रिप्ट ब्लॉक को समाप्त करता है, और इंजेक्ट किया गया <script> ब्लॉक निष्पादित होता है।
पेलोड एक बिना प्रमाणीकरण वाले हमलावर द्वारा लगाया जाता है, लेकिन निष्पादन के लिए एक विशेषाधिकार प्राप्त WordPress उपयोगकर्ता को प्रभावित व्यवस्थापक पृष्ठ खोलना आवश्यक है:
/wp-admin/admin.php?page=link_whisper_ai_subscription
इस लैब में, अलर्ट डायलॉग को ट्रिगर करने के लिए प्रभावित पृष्ठ को WordPress व्यवस्थापक के रूप में खोला जाता है।
यह समस्या को एक बिना प्रमाणीकरण के संग्रहीत XSS बनाता है जो प्रमाणीकृत WordPress व्यवस्थापकों या विशेषाधिकार प्राप्त उपयोगकर्ताओं को लक्षित करता है जो Link Whisper AI Subscription व्यवस्थापक पृष्ठ तक पहुँच सकते हैं।
Link Whisper Free 0.9.1 AI प्रमाणीकरण मानों को संग्रहीत करने से पहले सख्त सत्यापन जोड़ता है।
पैच किए गए हैंडलर को टोकन और उपयोगकर्ता आईडी को सख्त प्रारूपों से मेल खाना आवश्यक है: