Bird
Raised Fist0
Djangoframework~20 mins

SQL injection protection via ORM in Django - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
SQL Injection Defender
Get all challenges correct to earn this badge!
Test your skills under time pressure!
🧠 Conceptual
intermediate
1:30remaining
How does Django ORM protect against SQL injection?
Which of the following best explains how Django ORM prevents SQL injection attacks?
AIt automatically escapes query parameters and uses parameterized queries internally.
BIt disables all raw SQL queries by default to avoid injection.
CIt requires developers to manually sanitize all inputs before queries.
DIt encrypts all database queries before sending them to the database.
Attempts:
2 left
💡 Hint
Think about how query parameters are handled inside the ORM.
component_behavior
intermediate
1:30remaining
Output of a Django ORM filter with user input
Given the code below, what will be the output if user_input = "1 OR 1=1"?
Django
user_input = "1 OR 1=1"
results = MyModel.objects.filter(id=user_input)
print(results.query)
AEmpty queryset because filter fails
BSELECT ... WHERE id = 1 OR 1=1 (unsafe, injection possible)
CSyntaxError due to invalid filter argument
DSELECT ... WHERE id = '1 OR 1=1' (safe, no injection)
Attempts:
2 left
💡 Hint
Look at how Django ORM treats filter parameters as values, not code.
📝 Syntax
advanced
2:00remaining
Identify the unsafe raw SQL usage in Django
Which option shows unsafe raw SQL usage vulnerable to SQL injection?
AMyModel.objects.filter(name=user_input)
BMyModel.objects.raw("SELECT * FROM myapp_mymodel WHERE name = %s", [user_input])
CMyModel.objects.raw(f"SELECT * FROM myapp_mymodel WHERE name = '{user_input}'")
DMyModel.objects.get(pk=user_input)
Attempts:
2 left
💡 Hint
Look for string formatting inside raw SQL queries.
🔧 Debug
advanced
2:00remaining
Why does this Django raw query cause SQL injection?
Consider this code snippet:
query = "SELECT * FROM myapp_mymodel WHERE username = '%s'" % user_input
results = MyModel.objects.raw(query)
What is the main problem here?
AThe raw() method does not support parameterized queries.
BUser input is directly inserted into the query string without escaping.
CThe query uses single quotes instead of double quotes.
DThe query string is missing a WHERE clause.
Attempts:
2 left
💡 Hint
Think about how string formatting works with user input.
state_output
expert
2:30remaining
Result count after filtering with unsafe input in Django ORM
Given the model Product with integer field id, and this code:
user_input = "1 OR 1=1"
qs = Product.objects.filter(id=user_input)
count = qs.count()
What is the value of count if the database has 5 products with ids 1 to 5?
A0 because no product has id '1 OR 1=1'
B5 because the input causes SQL injection returning all rows
C1 because it matches product with id 1
DRaises a ValueError due to invalid integer filter
Attempts:
2 left
💡 Hint
Consider how Django ORM treats filter values and the field type.

Practice

(1/5)
1. Which of the following best explains how Django ORM protects against SQL injection?
easy
A. It automatically escapes user inputs when building queries.
B. It disables all user inputs by default.
C. It requires manual escaping of inputs in queries.
D. It converts all queries to raw SQL strings.

Solution

  1. Step 1: Understand Django ORM query building

    Django ORM builds SQL queries by safely escaping user inputs automatically.
  2. Step 2: Compare options with ORM behavior

    Only automatic escaping matches Django ORM's protection against SQL injection.
  3. Final Answer:

    It automatically escapes user inputs when building queries. -> Option A
  4. Quick 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
A. Model.objects.raw(f"SELECT * FROM table WHERE name = '{user_input}'")
B. Model.objects.filter("name = " + user_input)
C. Model.objects.filter(name=user_input)
D. Model.objects.execute_sql("SELECT * FROM table WHERE name = " + user_input)

Solution

  1. Step 1: Identify safe ORM filtering syntax

    Model.objects.filter(name=user_input) uses ORM's parameter binding and escapes input safely.
  2. Step 2: Analyze other options for unsafe practices

    Options A, B, and C build raw SQL strings or invalid syntax, risking injection.
  3. Final Answer:

    Model.objects.filter(name=user_input) -> Option C
  4. Quick 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
A. A raw SQL query that deletes the users table
B. An empty query with no filtering
C. A syntax error due to unescaped quotes
D. A safe SQL query with escaped input preventing injection

Solution

  1. Step 1: Understand ORM query with dangerous input

    ORM escapes dangerous characters in user_input to prevent SQL injection.
  2. Step 2: Analyze printed query behavior

    Printed query shows safe SQL with escaped input, not raw injection or errors.
  3. Final Answer:

    A safe SQL query with escaped input preventing injection -> Option D
  4. Quick 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
A. The raw() method automatically escapes inputs, so no error.
B. Using raw SQL with string formatting allows SQL injection.
C. The filter() method should be used instead of raw().
D. The query string is missing parameter placeholders.

Solution

  1. Step 1: Analyze string formatting with user input

    Using % formatting inserts user_input directly, risking SQL injection.
  2. Step 2: Understand raw() method behavior

    raw() executes raw SQL without escaping, so injection risk remains.
  3. Final Answer:

    Using raw SQL with string formatting allows SQL injection. -> Option B
  4. Quick 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
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 + "'")

Solution

  1. Step 1: Identify safe ORM filtering for email domain

    Using filter() with email__endswith=user_domain safely escapes input and builds query.
  2. 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.
  3. Final Answer:

    User.objects.filter(email__endswith=user_domain) -> Option A
  4. Quick 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