flawopen.com/Incidents/postgresql-psql-injection-beyondtrust-treasury-december-2024
CVE-2025-1094: PostgreSQL psql में SQL इंजेक्शन
जब ऐप escaped text से psql input बनाता था, अमान्य UTF-8 libpq escaping को bypass कर SQL या \! इंजेक्ट कर सकता था। 13 फ़रवरी 2025 को सुधार हुआ।
एक अनुवादक की कल्पना करें जिसका काम आपकी हर बात को उद्धरण-चिह्नों में रखना है, ताकि उसे कभी आदेश न समझा जाए। आपको पता चलता है कि अगर आप उसे किसी अनजान लिपि का शब्द दें, तो वह उलझ जाता है और एक उद्धरण-चिह्न छोड़ देता है। अब आपकी बात उद्धरण-चिह्नों से बाहर निकलकर निर्देश की तरह पढ़ी जाती है, जबकि अनुवादक ने हर उस इनपुट पर ठीक वैसा ही किया जिसके लिए उसे बनाया गया था और जिसे किसी ने परखा था।
इस पेज के मुख्य शब्द
PQescapeLiteral- libpq का एक फ़ंक्शन जो किसी मान को उद्धरण-चिह्नों में रखकर एस्केप करता है, ताकि उसे SQL टेक्स्ट में डाला जा सके। PQescapeIdentifier, PQescapeString और PQescapeStringConn भी प्रभावित थे।
अमान्य UTF-8- ऐसा बाइट क्रम जो घोषित एन्कोडिंग में सही ढंग से बना न हो। एस्केप कोड और psql इस पर सहमत नहीं थे कि ऐसे बाइट अपने बाद के कितने अक्षर निगल लेते हैं।
psql मेटा-कमांड- बैकस्लैश वाला कमांड जिसे सर्वर नहीं, psql क्लाइंट संभालता है। \! पंक्ति का बाक़ी हिस्सा ऑपरेटिंग-सिस्टम शेल कमांड की तरह चलाता है।
CVE-2024-12356- BeyondTrust Privileged Remote Access और Remote Support में कमांड इंजेक्शन की गंभीर ख़ामी। Rapid7 के परीक्षणों में इसके ज़रिए कोड चलाने के लिए
CVE-2025-1094ज़रूरी थी। बाउंड पैरामीटर- ऐसा मान जो SQL टेक्स्ट से अलग सर्वर को भेजा जाता है, ताकि उस पर उद्धरण या एस्केप का कोई निर्णय कभी लेना ही न पड़े।
फ्रेमवर्क मैपिंग
घटना का समयक्रम (Timeline)
कुछ Remote Support SaaS इंस्टेंस में सेंध की जाँच के बाद BeyondTrust ने CVE-2024-12356 पर सलाह BT24-10 प्रकाशित की; अमेरिकी ट्रेज़री ने बाद में बताया कि यह घटना उसके सिस्टम तक पहुँची थी।
CISA ने CVE-2024-12356 को Known Exploited Vulnerabilities सूची में जोड़ा।
PostgreSQL ने CVE-2025-1094 ठीक करने वाले 17.3, 16.7, 15.11, 14.16 और 13.19 जारी किए, और Rapid7 ने अपना विश्लेषण प्रकाशित किया।
हमले का चरण-दर-चरण प्रवाह
इनपुट एस्केप फ़ंक्शन तक पहुँचता है
एक एप्लिकेशन हमलावर से प्रभावित टेक्स्ट लेकर SQL कथन बनाने के लिए उसे PQescapeLiteral या libpq के किसी मिलते-जुलते फ़ंक्शन को देता है।
अमान्य UTF-8 एक उद्धरण-चिह्न छिपा लेता है
PostgreSQL की सलाह के अनुसार, एकल उद्धरण-चिह्न से पहले रखा गया गढ़ा हुआ अमान्य मल्टीबाइट क्रम एस्केप रूटीन को उस चिह्न को बिना एस्केप किए छोड़ने पर मजबूर कर देता था।
psql लिटरल को जल्दी बंद कर देता है
जब कथन psql को दिया जाता है, तो बिना एस्केप वाला उद्धरण-चिह्न स्ट्रिंग लिटरल को बंद कर देता है और बाक़ी इनपुट SQL या psql कमांड की तरह पढ़ा जाता है।
मेटा-कमांड शेल चलाता है
Rapid7 ने दिखाया कि इंजेक्ट किए गए टेक्स्ट में \! मेटा-कमांड हो सकता है, जिसे psql उसी मशीन पर ऑपरेटिंग-सिस्टम कमांड की तरह चलाता है जहाँ वह चल रहा है।
सोर्स कोड: कमज़ोर बनाम सुरक्षित कार्यान्वयन
यह psycopg 3 के साथ उदाहरण के लिए Python कोड है, BeyondTrust का कोड नहीं। कमज़ोर संस्करण सलाह में बताए गए जोखिम भरे पैटर्न को दोहराता है: libpq से मान एस्केप करना, उसे SQL टेक्स्ट में जोड़ना और वह टेक्स्ट psql को भेजना। मज़बूत संस्करण दोनों हिस्से हटा देता है: यह किसी भी प्रोसेसिंग से पहले ग़लत बने UTF-8 को अस्वीकार करता है और मान को असली ड्राइवर के ज़रिए बाउंड पैरामीटर की तरह भेजता है, इसलिए न कोई एस्केप चरण बचता है जिसे धोखा दिया जा सके, न रास्ते में psql का मेटा-कमांड पार्सर। जो कोड अब भी एस्केप करता है, उसके लिए libpq अपग्रेड करना ज़रूरी बना रहता है।
import subprocess
import psycopg
def lookup_user(conn: psycopg.Connection, name: bytes) -> bytes:
# libpq का PQescapeLiteral (17.3/16.7/15.11/14.16/13.19 से पहले) नहीं कर पाता था
# अमान्य UTF-8 बाइट अनुक्रम के पीछे छिपे उद्धरण चिह्न को निष्क्रिय करना।
literal = conn.pgconn.escape_literal(name)
script = b"SELECT id FROM users WHERE name = " + literal + b";\n"
# psql अपने इनपुट को स्क्रिप्ट की तरह चलाता है, जिसमें \! जैसे मेटा-कमांड भी शामिल हैं।
result = subprocess.run(["psql", "-At", "-d", "app"], input=script,
capture_output=True, check=True)
return result.stdout
import psycopg
MAX_NAME_CHARS = 128
def lookup_user(conn: psycopg.Connection, name: bytes) -> list[int]:
try:
text = name.decode("utf-8") # reject malformed input at the boundary
except UnicodeDecodeError:
raise ValueError("name is not valid UTF-8") from None
if len(text) > MAX_NAME_CHARS:
raise ValueError("name too long")
with conn.cursor() as cur:
# मान SQL टेक्स्ट से अलग, बाइंड पैरामीटर के रूप में भेजा जाता है,
# और कोई psql प्रक्रिया (इसलिए मेटा-कमांड पार्सर) शामिल नहीं होता।
cur.execute("SELECT id FROM users WHERE name = %s", (text,))
return [row[0] for row in cur.fetchall()]
इंजीनियरिंग और सिस्टम सुरक्षा चेकलिस्ट
- ✓कोडबेस में ऐसी subprocess कॉल खोजें जो psql चलाती हैं और जिनका इनपुट एप्लिकेशन डेटा से बनता है, उन्हें बाउंड पैरामीटर वाले डेटाबेस ड्राइवर से बदलें; नई कॉल पर विफल होने वाला CI नियम जोड़ें।
- ✓घोषित एन्कोडिंग में ग़लत बने इनपुट को सीमा पर ही अस्वीकार करें, इससे पहले कि वह किसी पार्सर, एस्केप फ़ंक्शन या डेटाबेस कॉल तक पहुँचे; b'\xc0\'' भेजकर सत्यापन त्रुटि की अपेक्षा करने वाला परीक्षण जोड़ें।
- ✓केवल सर्वर नहीं, libpq और क्लाइंट टूल भी अपग्रेड करें:
CVE-2025-1094PostgreSQL 17.3, 16.7, 15.11, 14.16 और 13.19 में ठीक है, और एप्लिकेशन होस्ट पर क्लाइंट पैकेज भी अपडेट होने चाहिए। - ✓जहाँ अभी एस्केप हटाया नहीं जा सकता, वहाँ एक रिग्रेशन परीक्षण जोड़ें जो एस्केप पथ में अमान्य UTF-8 के बाद उद्धरण-चिह्न भेजे और जाँचे कि नतीजा अस्वीकार हो या सुरक्षित रूप से उद्धृत हो।
- ✓विशेषाधिकार वाले रिमोट-एक्सेस टूल को अपनी हमले की सतह का हिस्सा मानें: उनके प्रबंधन इंटरफ़ेस सीमित करें, वेंडर की सूचना मिलते ही पैच करें और अनपेक्षित स्थानों से उनकी API कुंजियों के उपयोग पर नज़र रखें।