
Handlebars.js AST इंजेक्शन रिमोट कोड निष्पादन भेद्यता
यह पोस्ट EQSTLab द्वारा प्रकाशित एक शोध लेख है।
संदर्भित PoC: dinhvaren/cve-2026-33937
★ CVE-2026-33937 Handlebars.js AST इंजेक्शन रिमोट कोड एक्ज़ीक्यूशन PoC ★
https://github.com/user-attachments/assets/99e383e7-e71f-4e10-8c62-f50abff8b4f5
CVE-2026-33937 : Handlebars.js AST इंजेक्शन रिमोट कोड एक्ज़ीक्यूशन भेद्यता
| प्रभावित संस्करण | 4.0.0 – 4.7.8 |
| पैच किया गया संस्करण | 4.7.9 |
| CVSS स्कोर | 9.8 (क्रिटिकल) |
Handlebars.js में एक Type Confusion भेद्यता इस तथ्य से उत्पन्न होती है कि Handlebars.compile() न केवल एक टेम्पलेट स्ट्रिंग को, बल्कि एक pre-parsed AST ऑब्जेक्ट (JSON) को भी अपने इनपुट के रूप में स्वीकार करता है। एक हमलावर जो compile() को पारित मान को नियंत्रित करता है, एक क्राफ्टेड AST ऑब्जेक्ट प्रदान कर सकता है जिसमें NumberLiteral नोड के value फ़ील्ड को एक मनमानी JavaScript स्ट्रिंग से बदल दिया गया हो। चूँकि आंतरिक कोड जनरेटर उस फ़ील्ड को बिना sanitization के सीधे उत्सर्जित JavaScript फ़ंक्शन बॉडी में डालता है, परिणामी फ़ंक्शन रेंडर होने पर हमलावर-नियंत्रित कोड निष्पादित करता है — जिससे सर्वर पर Remote Code Execution प्राप्त होती है।
Docker का उपयोग करके भेद्य वातावरण बनाएँ और चलाएँ:
इमेज बनाएँ
docker build -t cve-2026-33937-server .
कंटेनर चलाएँ
docker run --name cve-2026-33937 -p 12701:12701 -p 9229:9229 cve-2026-33937-server
या दिए गए npm स्क्रिप्ट का उपयोग करें:
npm run docker:up # build + run in one step
एप्लिकेशन http://localhost:12701 पर serve किया जाता है।
वेब UI
ब्राउज़र में http://localhost:12701 खोलें। यह पेज एक B2B ईमेल बिल्डर इंटरफ़ेस प्रस्तुत करता है। उपयोगकर्ता द्वारा प्रदान किए गए फ़ील्ड मानों को क्लाइंट साइड पर एक Handlebars टेम्पलेट स्ट्रिंग में interpolate किया जाता है और फिर रेंडरिंग के लिए सर्वर पर पोस्ट किया जाता है। इनपुट फ़ील्ड के माध्यम से या सीधे API के माध्यम से एक दुर्भावनापूर्ण Handlebars पेलोड इंजेक्ट करें।
सीधा API
# POST crafted template to the vulnerable endpoint
curl -s -X POST http://localhost:12701/api/email/preview \
-H "Content-Type: application/json" \
-d '{"subject":"test","editorTemplateData":"<PAYLOAD>"}'
<PAYLOAD> को Handlebars.compile() को लक्षित करने वाले AST इंजेक्शन पेलोड से बदलें।
POST /api/email/preview
सर्वर editorTemplateData युक्त एक JSON बॉडी स्वीकार करता है और उसे बिना किसी sanitization या allowlist प्रवर्तन के सीधे Handlebars.compile() को भेजता है:
// app.js
const renderEmail = Handlebars.compile(editorTemplateData);
Handlebars.compile() को एक टेम्पलेट स्ट्रिंग स्वीकार करने के रूप में प्रलेखित किया गया है, लेकिन इसकी आंतरिक प्रकार जाँच एक pre-parsed AST ऑब्जेक्ट को सीधे पारित करने की भी अनुमति देती है। javascript-compiler.js के अंदर, NumberLiteral() विज़िटर बिना किसी प्रकार सत्यापन या sanitization के नोड के value फ़ील्ड को उत्पन्न JavaScript स्रोत में शब्दशः उत्सर्जित करता है:
// javascript-compiler.js (simplified)
NumberLiteral(number) {
this.pushStackLiteral(number.value); // value inserted as-is into emitted JS
}
यदि कोई हमलावर एक क्राफ्टेड AST ऑब्जेक्ट प्रदान करता है जहाँ number.value एक संख्यात्मक literal के बजाय मनमानी JavaScript युक्त एक स्ट्रिंग है (जैसे, "1; require('child_process').execSync(...)"), तो उत्सर्जित फ़ंक्शन बॉडी रेंडर समय पर उस कोड को शामिल करती है और निष्पादित करती है।
भेद्य एप्लिकेशन में खतरनाक पैटर्न है:
const render = Handlebars.compile(userInput); // userInput may be a crafted AST object
render(safeContextData); // attacker code runs here
शोषण तकनीक पर नोट: मौजूदा सार्वजनिक PoC (संदर्भित एक सहित)
NumberLiteralनोड कोlookupहेल्पर के साथ जोड़कर इंजेक्शन प्राप्त करते हैं। यह PoCBooleanLiteralनोड कोlogबिल्ट-इन हेल्पर के साथ जोड़कर उसी RCE प्राइमेटिव की पुष्टि करता है, यह दर्शाता है कि type confusion केवल एक नोड प्रकार या हेल्पर फ़ंक्शन तक सीमित नहीं है।
editorTemplateData मान के साथ /api/email/preview पर POST अनुरोध प्रस्तुत करता है।Handlebars.compile() को कॉल करता है।render() को कॉल करने से सर्वर प्रक्रिया में मनमानी JavaScript का निष्पादन ट्रिगर होता है।जब Handlebars को Node.js बैकएंड वातावरण में लागू किया जाता है, तो यह भेद्यता मानक क्लाइंट-साइड XSS के विपरीत, सर्वर-साइड कोड निष्पादन पथ की ओर ले जाती है। हमले के लिए किसी उपयोगकर्ता को कोई आउटपुट reflect होने की आवश्यकता नहीं होती; पेलोड एप्लिकेशन के समान विशेषाधिकारों के साथ Node.js प्रक्रिया के भीतर निष्पादित होता है। परिनियोजन के आधार पर:
/etc/passwd) पढ़ी और exfiltrate की जा सकती हैं।+-------------------------------------------+
| Attacker |
+-------------------------------------------+
|
| POST /api/email/preview
| {"editorTemplateData": "<malicious payload>"}
v
+-------------------------------------------+
| Handlebars.compile(editorTemplateData) |
| (No sanitization — app.js:17) |
+-------------------------------------------+
|
| AST node injection
| breaks template sandbox
v
+-------------------------------------------+
| Arbitrary JS Execution (Server Process) |
+-------------------------------------------+
|
| Read sensitive files, spawn shell,
| exfiltrate secrets, etc.
v
+-------------------------------------------+
| Remote Code Execution (RCE) |
+-------------------------------------------+
Handlebars.js को 4.7.9 या बाद के संस्करण में अपग्रेड करें।
संस्करण 4.7.9 compile() में सख्त इनपुट प्रकार सत्यापन प्रस्तुत करता है, कोड जनरेशन शुरू होने से पहले गैर-स्ट्रिंग तर्कों को अस्वीकार करता है।
compile() को कॉल करने से पहले एक प्रकार जाँच लागू करें।
यदि तत्काल अपग्रेड संभव नहीं है, तो कॉल साइट पर सत्यापित करें कि तर्क हमेशा एक string है:
if (typeof templateInput !== 'string') throw new TypeError('Template must be a string');
const render = Handlebars.compile(templateInput);
बिल्ड-टाइम pre-compilation के लिए handlebars/runtime का उपयोग करें।
टेम्पलेट्स को बिल्ड समय पर Handlebars CLI के साथ pre-compile करें और केवल runtime बंडल भेजें। runtime बिल्ड में compile() शामिल नहीं होता, जिससे प्रोडक्शन परिनियोजन के लिए आक्रमण सतह पूरी तरह समाप्त हो जाती है।
यह रिपॉजिटरी केवल सुरक्षा अनुसंधान, शिक्षा और नियंत्रित भेद्यता प्रदर्शन के लिए है। इसका उपयोग सिस्टम स्वामी से स्पष्ट लिखित प्राधिकरण के बिना सिस्टम का परीक्षण या शोषण करने के लिए नहीं किया जाना चाहिए। इस परियोजना का उद्देश्य सुरक्षा शोधकर्ताओं, डिफेंडरों और डेवलपर्स को भेद्यता को समझने, नियंत्रित लैब वातावरण में जोखिम को मान्य करने और प्रभावी शमन लागू करने में मदद करना है।