Kodokon kodokon.com

सुरक्षा: SQL इंजेक्शन, विशेषाधिकार, प्रिपेयर्ड स्टेटमेंट

एक SQL इंजेक्शन को दोहराएँ, उसे प्रिपेयर्ड स्टेटमेंट से निष्प्रभावी करें, और न्यूनतम विशेषाधिकार लागू करें।

11 मिनट · 3 प्रश्न

इस पाठ को Kodokon में खोलें

एक SQL इंजेक्शन उसी क्षण होता है जब अविश्वसनीय डेटा को किसी क्वेरी के टेक्स्ट में जोड़ा (concatenate) जाता है। हमलावर एक ऐसी वैल्यू देता है जो स्ट्रिंग को बंद कर देती है और तर्क को हाईजैक कर लेती है। आइए users टेबल पर हमले को दोहराएँ: इनपुट ada' OR '1'='1 को सीधे जोड़ना एक सटीक फ़िल्टर को हमेशा-सही शर्त में बदल देता है।

SQL
CREATE TABLE users (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  is_admin INTEGER NOT NULL DEFAULT 0
);

INSERT INTO users (id, name, is_admin)
VALUES (1, 'ada', 0), (2, 'root', 1);

-- Dangerous concatenation (NEVER do this)
-- input = ada' OR '1'='1
SELECT * FROM users
WHERE name = 'ada' OR '1'='1';
इंजेक्ट की गई क्वेरी सभी रो लौटाती है।

पेलोड काम करता है क्योंकि उद्धरण चिह्न समय से पहले लिटरल 'ada' को बंद कर देता है, फिर OR '1'='1' एक सार्वभौमिक रूप से सही शर्त जोड़ देता है। एक रूप मूल क्वेरी के बाकी हिस्से को कमेंट करने के लिए -- जोड़ता है। सबक: जब तक डेटा और कोड एक ही स्ट्रिंग साझा करते हैं, तब तक कोई भी मैनुअल एस्केपिंग वास्तव में भरोसेमंद नहीं है।

SQL
-- Positional placeholder
SELECT * FROM users WHERE name = ?;

-- Named placeholder
SELECT * FROM users WHERE name = :name;
SQLite में बाउंड पैरामीटर के दो रूप।

इसका उपाय है प्रिपेयर्ड स्टेटमेंट: ड्राइवर पहले क्वेरी की संरचना को कंपाइल करता है, फिर वैल्यू को अलग से बाइंड करता है। बाउंड डेटा को कभी SQL के रूप में पार्स नहीं किया जाता, केवल तुलना की जाती है। एक अतिरिक्त लाभ के रूप में, कंपाइल की गई संरचना पुनः उपयोग योग्य है: क्रमिक रूप से कई वैल्यू बाइंड करना हर कॉल पर प्लान को दोबारा कंपाइल करने से बचाता है।

SQL
-- The bound value stays data, not SQL
SELECT * FROM users
WHERE name = :name;
-- :name = ada' OR '1'='1
-- -> 0 rows: no user
--    is literally named that
वही पेलोड, अब हानिरहित।

ज्ञान जांच

सुनिश्चित करें कि आपको इस पाठ के मुख्य बिंदु याद हैं।

  1. पैरामीटर वाला प्रिपेयर्ड स्टेटमेंट SQL इंजेक्शन को क्यों रोकता है?
    • क्योंकि यह प्रेषित वैल्यू को एन्क्रिप्ट करता है
    • क्योंकि बाउंड वैल्यू को डेटा माना जाता है, कभी SQL के रूप में पार्स नहीं किया जाता
    • क्योंकि यह स्ट्रिंग में उद्धरण चिह्नों को स्वचालित रूप से एस्केप करता है
    • क्योंकि यह उपयोगकर्ता इनपुट की लंबाई सीमित करता है
  2. पेलोड ' OR '1'='1 इंजेक्शन में सफल होता है क्योंकि यह...
    • डेटाबेस सर्वर की मेमोरी को संतृप्त कर देता है
    • स्ट्रिंग लिटरल को बंद करता है फिर एक हमेशा-सही शर्त जोड़ता है
    • क्वेरी द्वारा लक्षित टेबल को ड्रॉप कर देता है
    • वर्तमान उपयोगकर्ता के विशेषाधिकार बदल देता है
  3. क्या आप किसी टेबल के नाम को ? पैरामीटर के माध्यम से बाइंड कर सकते हैं?
    • हाँ, प्लेसहोल्डर किसी भी प्रकार के पहचानकर्ता को स्वीकार करते हैं
    • नहीं: प्लेसहोल्डर केवल वैल्यू बाइंड करते हैं; किसी पहचानकर्ता को श्वेतसूची के विरुद्ध सत्यापित किया जाना चाहिए
    • हाँ, लेकिन केवल नामित रूप :name के साथ
    • हाँ, बशर्ते टेबल पहले से मौजूद हो