SQL injection is a security risk where bad users can change your database commands. Using Django's ORM helps stop this by safely handling data for you.
SQL injection protection via ORM in Django
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
Django
Model.objects.filter(field_name=value)
Model.objects.get(id=value)
Model.objects.create(field_name=value)Django ORM automatically escapes values to prevent SQL injection.
Never use raw SQL queries with string concatenation for user input.
Examples
Django
User.objects.filter(username=username_input)Django
Product.objects.get(id=product_id)
Django
Order.objects.create(user=user_obj, total=order_total)
Sample Program
This example shows how Django ORM safely handles a tricky username input that tries SQL injection. The ORM treats the input as plain text, so no injection happens.
Django
from django.db import models class User(models.Model): username = models.CharField(max_length=100) # Imagine this username comes from a user input form username_input = "admin' OR '1'='1" # Using ORM filter to safely query users = User.objects.filter(username=username_input) print(f"Number of users found: {users.count()}")
Important Notes
Always use Django ORM methods like filter(), get(), and create() to handle user data safely.
Avoid using raw() queries with string formatting or concatenation for user input.
Django ORM escapes inputs automatically, so you don't have to do it manually.
Summary
Django ORM protects your app from SQL injection by safely handling user data.
Use ORM methods instead of raw SQL queries with user input.
This keeps your database and app secure and your code easier to write.
Practice
1. Which of the following best explains how Django ORM protects against SQL injection?
easy
Solution
Step 1: Understand Django ORM query building
Django ORM builds SQL queries by safely escaping user inputs automatically.Step 2: Compare options with ORM behavior
Only automatic escaping matches Django ORM's protection against SQL injection.Final Answer:
It automatically escapes user inputs when building queries. -> Option AQuick Check:
Django ORM auto-escapes inputs = C [OK]
Hint: Remember: ORM escapes inputs automatically to prevent injection [OK]
Common Mistakes:
- Thinking ORM disables inputs
- Believing manual escaping is needed
- Assuming ORM uses raw SQL strings
2. Which Django ORM method is safe to use for filtering records with user input?
easy
Solution
Step 1: Identify safe ORM filtering syntax
Model.objects.filter(name=user_input) uses ORM's parameter binding and escapes input safely.Step 2: Analyze other options for unsafe practices
Options A, B, and C build raw SQL strings or invalid syntax, risking injection.Final Answer:
Model.objects.filter(name=user_input) -> Option CQuick Check:
Use filter() with keyword args for safe queries = D [OK]
Hint: Use filter() with keyword arguments, not raw SQL strings [OK]
Common Mistakes:
- Using raw SQL with string concatenation
- Passing raw SQL strings to filter()
- Ignoring ORM's parameter binding
3. What will be the output of this Django ORM query if user_input = "Robert'); DROP TABLE users;--"?
users = User.objects.filter(username=user_input) print(users.query)
medium
Solution
Step 1: Understand ORM query with dangerous input
ORM escapes dangerous characters in user_input to prevent SQL injection.Step 2: Analyze printed query behavior
Printed query shows safe SQL with escaped input, not raw injection or errors.Final Answer:
A safe SQL query with escaped input preventing injection -> Option DQuick Check:
ORM escapes dangerous input = B [OK]
Hint: ORM escapes dangerous input, so injection won't happen [OK]
Common Mistakes:
- Assuming raw SQL runs as is
- Expecting syntax errors from quotes
- Thinking ORM ignores dangerous input
4. Identify the error in this Django ORM code that tries to prevent SQL injection:
query = "SELECT * FROM users WHERE username = '%s'" % user_input users = User.objects.raw(query)
medium
Solution
Step 1: Analyze string formatting with user input
Using % formatting inserts user_input directly, risking SQL injection.Step 2: Understand raw() method behavior
raw() executes raw SQL without escaping, so injection risk remains.Final Answer:
Using raw SQL with string formatting allows SQL injection. -> Option BQuick Check:
String formatting + raw() = injection risk = A [OK]
Hint: Never build raw SQL with string formatting; use ORM methods [OK]
Common Mistakes:
- Assuming raw() escapes inputs
- Using raw SQL instead of filter()
- Ignoring injection risk in string formatting
5. You want to safely filter users by email domain using Django ORM. Which approach correctly prevents SQL injection?
user_domain = request.GET.get('domain')
# Which code is safe?
A) User.objects.filter(email__endswith=user_domain)
B) User.objects.raw(f"SELECT * FROM users WHERE email LIKE '%{user_domain}'")
C) User.objects.filter(email__endswith='%' + user_domain)
D) User.objects.raw("SELECT * FROM users WHERE email LIKE '%" + user_domain + "'")hard
Solution
Step 1: Identify safe ORM filtering for email domain
Using filter() with email__endswith=user_domain safely escapes input and builds query.Step 2: Analyze raw() and string concatenation risks
Options B and D use raw SQL with string interpolation, risking injection. User.objects.filter(email__endswith='%' + user_domain) incorrectly adds '%' in Python string, not ORM pattern.Final Answer:
User.objects.filter(email__endswith=user_domain) -> Option AQuick Check:
Use ORM filter with lookup for safe input handling = A [OK]
Hint: Use ORM lookups like __endswith, avoid raw SQL with user input [OK]
Common Mistakes:
- Using raw SQL with user input directly
- Adding SQL wildcards in Python strings
- Ignoring ORM's safe query building
