flawopen.com/SQL इंजेक्शन
SQL इंजेक्शन
SQL इंजेक्शन तब होता है जब कोई ऐप्लिकेशन यूज़र इनपुट को SQL टेक्स्ट में चिपकाकर क्वेरी बनाता है, और डेटाबेस उस इनपुट के एक हिस्से को कमांड की तरह पढ़ लेता है। सुधार हर भाषा में एक ही है: क्वेरी को प्लेसहोल्डर के साथ भेजें और मान अलग से दें। सटीक API कॉल, कमज़ोर और सुधरा कोड, और इसे पकड़ने वाले CI नियम देखने के लिए नीचे अपनी भाषा चुनें।
आसान भाषा में (ELI5)
आप लाइब्रेरियन को एक पर्ची देते हैं जिस पर लिखा है 'इस व्यक्ति का रिकॉर्ड निकालें: ___' और खाली जगह में लिखते हैं: 'राहुल। और हाँ, रिकॉर्ड-रूम खोलकर सारी फ़ाइलें भी ले आइए।' जो लाइब्रेरियन पूरी पर्ची को एक ही निर्देश मानकर पढ़ता है, वह दोनों काम कर देगा। यूज़र इनपुट को SQL स्ट्रिंग में चिपकाने से ठीक ऐसी ही पर्ची बनती है। पैरामीटराइज़्ड क्वेरी एक छपा हुआ फ़ॉर्म है जिसमें 'नाम' का खाना सील किया हुआ है: उसके अंदर कुछ भी लिखा हो, उसे सिर्फ़ नाम के रूप में ही खोजा जाता है।
इस पेज के मुख्य शब्द
- SQL injection (CWE-89)
- अविश्वसनीय इनपुट SQL टेक्स्ट में जोड़ा या फ़ॉर्मेट किया जाता है, इसलिए इनपुट के कोट, कीवर्ड और ऑपरेटर एक मान माने जाने के बजाय क्वेरी की संरचना बदल देते हैं।
- Prepared statement and bind parameters
- क्वेरी प्लेसहोल्डर (
?,$1,:name) के साथ भेजी जाती है और कोई भी मान पहुँचने से पहले पार्स हो जाती है; मान अलग से जाते हैं और हमेशा डेटा माने जाते हैं। हर ड्राइवर और ORM में यही मुख्य बचाव है। - Blind SQL injection
- जब पेज न क्वेरी के नतीजे दिखाए न त्रुटियाँ, तब हमलावर रिस्पॉन्स के अंतर (boolean-based) या उसके समय (time-based) से एक-एक बिट करके डेटा निकालता है। दिखने वाला आउटपुट न होने का मतलब यह नहीं कि कमज़ोरी नहीं है।
- Second-order SQL injection
- कोई मान सुरक्षित रूप से सेव होता है, फिर बाद में आपके अपने डेटाबेस से पढ़कर किसी दूसरी क्वेरी में जोड़ दिया जाता है। हर क्वेरी पैरामीटराइज़ होनी चाहिए, उन क्वेरी समेत जिनका इनपुट आपकी अपनी टेबल से आता है।
- Identifiers and allowlists
- प्लेसहोल्डर सिर्फ़ मान ले जाते हैं, टेबल के नाम, कॉलम के नाम या सॉर्ट की दिशा नहीं। इन्हें कोड में तय अनुमति-सूची से चुनना होगा, कभी रिक्वेस्ट से कॉपी नहीं करना।
हमले का चरण-दर-चरण प्रवाह
इनपुट क्वेरी तक पहुँचता है
कोई फ़ॉर्म फ़ील्ड, URL पैरामीटर, header या API फ़ील्ड SQL स्टेटमेंट बनाने वाले कोड को दिया जाता है।
इनपुट SQL टेक्स्ट में चिपका दिया जाता है
स्ट्रिंग जोड़ना, interpolation या फ़ॉर्मेटिंग मान को सीधे डाल देते हैं। हानिरहित टेस्ट मान ' OR '1'='1 WHERE name = '...' को हमेशा सही रहने वाली शर्त बना देता है।
डेटाबेस उसे सिंटैक्स की तरह पार्स करता है
डेटाबेस को एक ही स्ट्रिंग मिलती है, वह नहीं जान सकता कि कौन-सा हिस्सा यूज़र से आया, और बदले हुए स्टेटमेंट को ऐप्लिकेशन के अधिकारों से चला देता है।
डेटा पढ़ा, बदला या मिटाया जाता है
क्वेरी और अकाउंट के अनुसार हमलावर लॉगिन बायपास करता है, UNION क्वेरी से टेबल निकाल लेता है या blind तरीके से डेटा निकालता है। 2023 का MOVEit Transfer उल्लंघन (CVE-2023-34362) इसी तरह की कमज़ोरी से शुरू हुआ था।
भाषा के अनुसार SQL इंजेक्शन गाइड
इंजीनियरिंग और सिस्टम सुरक्षा चेकलिस्ट
- मान वाली हर क्वेरी को पैरामीटराइज़ करें, ORM के raw-SQL रास्तों समेत, आंतरिक या संख्यात्मक इनपुट के लिए भी कोई छूट नहीं।
- टेबल के नाम, कॉलम के नाम और सॉर्ट की दिशा कोड में तय अनुमति-सूची से चुनें।
- CI में स्ट्रिंग से बने SQL के लिए SAST नियम चलाएँ (Bandit, gosec, Semgrep, CodeQL, Find Security Bugs, Brakeman या Psalm) और नए नतीजों पर बिल्ड फ़ेल करें।
- न्यूनतम अधिकार वाले डेटाबेस रोल से कनेक्ट करें: न DDL, न सुपरयूज़र, सिर्फ़ वही टेबल जिनकी सेवा को ज़रूरत है।
- एस्केप फ़ंक्शन और WAF नियमों को सिर्फ़ अतिरिक्त परत मानें; वे बिना कोट वाले संदर्भ और एनकोडिंग की चालें चूक जाते हैं।
- क्लाइंट को सामान्य त्रुटि संदेश लौटाएँ और डेटाबेस त्रुटियाँ सर्वर पर लॉग करें, ताकि क्वेरी की संरचना कभी उजागर न हो।
स्रोत
- CWE-89: SQL Injection
- OWASP SQL Injection रोकथाम Cheat Sheet
- CISA — CL0P ransomware अभियान ने MOVEit SQL Injection का दुरुपयोग किया