flawopen.com/Python में SQL Injection/Django ORM
क्या Django ORM डिफ़ॉल्ट रूप से SQL Injection से बचाता है?
Django के सामान्य QuerySet API जैसे .filter(), .get() और .exclude() SQL को values से अलग रखते हैं और values को database driver तक parameters के रूप में भेजते हैं। यह सुरक्षा query बनाने के हर तरीके को कवर नहीं करती: raw SQL, custom expressions और user द्वारा चुनी गई query structure की अलग समीक्षा आवश्यक है।
Django QuerySet में values सुरक्षित रूप से देना
username = request.GET.get("u", "")
User.objects.raw(
f"SELECT * FROM myapp_user WHERE username = '{username}'"
)
username = request.GET.get("u", "")
User.objects.raw(
"SELECT * FROM myapp_user WHERE username = %s",
[username],
)
जहाँ सुरक्षा की अलग जाँच ज़रूरी है
Manager.raw() दिया गया SQL चलाता है। User-controlled values को params से दें और placeholders को quotes में न रखें, जैसे User.objects.raw("SELECT * FROM users WHERE username = %s", [username])। Values को f-string, % formatting या concatenation से SQL में न जोड़ें। Parameters values के लिए हैं, table या column जैसे SQL identifiers के लिए नहीं।
सीधे database तक पहुँचने पर cursor.execute(sql, params) उपयोग करें और Django के documented placeholders के अनुसार values अलग दें। sql में values interpolate न करें। RawSQL और Func expressions भी जाँचें: template context और keyword arguments parameters के बजाय SQL में interpolate हो सकते हैं।
.filter(**{field: value}) में user-controlled field path अपने-आप SQL Injection नहीं है; Django lookup names को query structure मानकर resolve करता है। फिर भी इससे ऐसे fields, relations या lookups सामने आ सकते हैं जिन्हें endpoint को उपलब्ध नहीं कराना चाहिए, और errors भी हो सकते हैं। बाहरी sort/filter विकल्पों को अनुमत model fields और lookups की छोटी allow-list से map करें।
Django queries का audit कैसे करें
rg -n '(\.raw\(|RawSQL\(|\.extra\(|connection\.cursor\()' --glob '*.py' ..raw(), RawSQL, .extra() और connection.cursor() खोजें। हर परिणाम में values का रास्ता देखें: bound parameters, untrusted SQL fragments, dynamic identifiers या lookups और custom Func templates की जाँच करें।अक्सर पूछे जाने वाले प्रश्न
QuerySet.extra() raw SQL fragments जोड़ने वाला पुराना API है। नए code में इससे बचें और मौजूदा where व select arguments की सावधानी से समीक्षा करें। QuerySet expressions को प्राथमिकता दें; raw SQL आवश्यक हो तो documented params से values bind करें।
Django REST Framework ORM की SQL parameterization नहीं बदलता। Views, serializers और viewsets से बनी queries पर भी यही नियम लागू हैं; client-controlled sort और filter fields को भी allow-list से सीमित करें।
संदर्भ
- Django docs — SQL injection protection
- flawopen.com — SQL Injection in Python
- Django docs — Performing raw SQL queries
- Django docs — Query expressions and RawSQL