पाठ 10 / 28

मॉडल आउटपुट के रास्ते SQL Injection

देखें injected मान हर row लीक करता है, और parameterised उपाय।

प्राकृतिक भाषा से SQL में अतिरिक्त सावधानी चाहिए

आम सुविधा है "अपने database से बात करें": मॉडल सवाल को SQL में बदलता है। App मॉडल जो भी SQL लिखे उसे चला दे, तो user (या मॉडल द्वारा पढ़ा दस्तावेज़) उससे DROP TABLE, ऐसी table पर query जिसे user को नहीं देखना चाहिए, या महँगी query बनवा सकता है जो database अटका दे। सुरक्षित डिज़ाइन: मॉडल SQL लिखने की जगह निश्चित, पहले से लिखी queries के parameters भरे; मुक्त-रूप SQL अपरिहार्य हो तो विशिष्ट views तक सीमित केवल-पढ़ने वाले database account से जुड़ें, row-level security जोड़ें, कथन प्रकार parse कर allow-list करें (सिर्फ़ SELECT), timeouts और row सीमाएँ लगाएँ, और admin account से कभी न चलाएँ। मॉडल द्वारा दिए मानों के लिए हमेशा parameters उपयोग करें, जैसा उदाहरण दिखाता है: वही दुर्भावनापूर्ण मान query में जोड़ने पर हर row लौटाता है, और parameter के रूप में देने पर कोई नहीं।

Concatenation बनाम parameters, चलाकर

मैंने यह सादे Python 3 (सिर्फ़ standard library) से चलाया। यहाँ सारे हमले स्थानीय डेटा पर हानिरहित प्रदर्शन हैं, कोई असली system उपयोग नहीं हुआ। "मॉडल आउटपुट" asha' OR '1'='1 जोड़ी गई query का अर्थ बदल देता है ताकि वह तीनों ग्राहक लौटाए। Bound parameter के रूप में वही पाठ सिर्फ़ मान है, किसी ग्राहक नाम से मेल नहीं खाता और कुछ नहीं लौटाता।

import sqlite3

db = sqlite3.connect(":memory:")
db.executescript("""
create table orders (id integer, customer text, total integer);
insert into orders values (1, 'asha', 500), (2, 'ravi', 900), (3, 'meera', 1200);
""")
model_output = "asha' OR '1'='1"               # text a model produced from a user's message (attacker-influenced)

unsafe = f"select id, customer from orders where customer = '{model_output}'"
print("UNSAFE rows:", db.execute(unsafe).fetchall())
print("SAFE   rows:", db.execute("select id, customer from orders where customer = ?", (model_output,)).fetchall())

Output:

UNSAFE rows: [(1, 'asha'), (2, 'ravi'), (3, 'meera')]
SAFE   rows: []

केवल-पढ़ने वाले database accounts उपयोग करें

ग़लत query निकल भी जाए तो विशिष्ट views पर केवल-पढ़ने वाला account नुक़सान सीमित रखता है।

त्वरित जाँच: "database के बारे में सवाल पूछें" के लिए सबसे सुरक्षित डिज़ाइन कौन-सा है?

  • मॉडल निश्चित queries के parameters भरे, या कड़ी सीमाओं के साथ केवल-पढ़ने वाला SQL चलाए
  • मॉडल का लिखा कोई भी SQL admin के रूप में चलाएँ
  • Authentication बंद करें
  • Passwords prompt में रखें
Answer

मॉडल निश्चित queries के parameters भरे, या कड़ी सीमाओं के साथ केवल-पढ़ने वाला SQL चलाए — मॉडल को parameters और न्यूनतम-विशेषाधिकार पहुँच तक सीमित करें।