FlawOpen

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 सुरक्षित रूप से देना

असुरक्षित — raw SQL में input interpolate करना
username = request.GET.get("u", "")
User.objects.raw(
    f"SELECT * FROM myapp_user WHERE username = '{username}'"
)
सुरक्षित — raw() के params से input bind करना
username = request.GET.get("u", "")
User.objects.raw(
    "SELECT * FROM myapp_user WHERE username = %s",
    [username],
)

जहाँ सुरक्षा की अलग जाँच ज़रूरी है

Model.objects.raw()

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 के लिए नहीं।

connection.cursor() से सीधी पहुँच

सीधे database तक पहुँचने पर cursor.execute(sql, params) उपयोग करें और Django के documented placeholders के अनुसार values अलग दें। sql में values interpolate न करें। RawSQL और Func expressions भी जाँचें: template context और keyword arguments parameters के बजाय SQL में interpolate हो सकते हैं।

User-controlled field paths

.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 की जाँच करें।

अक्सर पूछे जाने वाले प्रश्न

क्या extra() सुरक्षित है?

QuerySet.extra() raw SQL fragments जोड़ने वाला पुराना API है। नए code में इससे बचें और मौजूदा where व select arguments की सावधानी से समीक्षा करें। QuerySet expressions को प्राथमिकता दें; raw SQL आवश्यक हो तो documented params से values bind करें।

क्या यह Django REST Framework पर भी लागू है?

Django REST Framework ORM की SQL parameterization नहीं बदलता। Views, serializers और viewsets से बनी queries पर भी यही नियम लागू हैं; client-controlled sort और filter fields को भी allow-list से सीमित करें।

संदर्भ

यह भी देखें SQL इंजेक्शन (CWE-89): यह कैसे काम करता है और हर भाषा में इसे कैसे रोकें — flawopen.com Doctrine ORM में SQL Injection: सुरक्षित queries EF Core FromSqlRaw: सुरक्षित पैरामीटरयुक्त SQL FastAPI SQL इंजेक्शन: Pydantic क्या रोकता है और क्या नहीं GORM Raw SQL: Go में SQL injection रोकें क्या Quotes Escape करना SQL Injection रोकने के लिए काफ़ी है? SQL इंजेक्शन रोकने के लिए ORM का उपयोग काफ़ी है?