Bird
Raised Fist0
Flaskframework~20 mins

SQL injection prevention in Flask - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
SQL Injection Prevention Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
🧠 Conceptual
intermediate
2:00remaining
Why use parameterized queries in Flask?

Which of the following best explains why parameterized queries help prevent SQL injection attacks in Flask applications?

AThey automatically sanitize HTML output to prevent script injection.
BThey encrypt the database connection to block attackers.
CThey separate SQL code from data, so user input cannot change the query structure.
DThey limit the number of database connections to prevent overload.
Attempts:
2 left
💡 Hint

Think about how user input is handled inside the SQL command.

❓ component_behavior
intermediate
2:00remaining
Output of unsafe query with user input

Consider this Flask code snippet using raw string formatting for SQL:

user_id = "1 OR 1=1"
query = f"SELECT * FROM users WHERE id = {user_id}"
cursor.execute(query)
result = cursor.fetchall()

What will result contain?

AOnly the row with id = 1, because the input is treated as a string.
BAll rows from the users table, because the condition always evaluates to true.
CAn empty list, because the query is invalid.
DA syntax error is raised due to improper query formatting.
Attempts:
2 left
💡 Hint

Look at how the user input changes the WHERE clause.

📝 Syntax
advanced
2:00remaining
Correct parameterized query syntax in Flask

Which of the following Flask code snippets correctly uses parameterized queries to safely select a user by id?

Acursor.execute("SELECT * FROM users WHERE id = :user_id", {'user_id': user_id})
Bcursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
Ccursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
Dcursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
Attempts:
2 left
💡 Hint

Check the parameter style and how parameters are passed as a tuple.

🔧 Debug
advanced
2:00remaining
Identify the error in parameterized query usage

What error will this Flask code raise?

user_id = 5
cursor.execute("SELECT * FROM users WHERE id = ?", user_id)
ATypeError because parameters must be in a sequence like a tuple or list.
BSyntaxError due to missing quotes around the placeholder.
COperationalError because the placeholder ? is invalid in this database.
DNo error; the query runs successfully.
Attempts:
2 left
💡 Hint

Look at how parameters are passed to execute.

❓ state_output
expert
2:00remaining
Result of mixed safe and unsafe query parts

Given this Flask code:

user_input = "1; DROP TABLE users;"
query = "SELECT * FROM users WHERE id = " + user_input
cursor.execute(query)
rows = cursor.fetchall()

What will happen when this code runs?

AA syntax error occurs because multiple statements are not allowed in one execute call.
BThe database executes the SELECT and then drops the users table, causing data loss.
COnly the SELECT runs safely; the DROP TABLE is ignored by the database.
DThe query returns no rows but the users table remains intact.
Attempts:
2 left
💡 Hint

Consider how the database driver handles multiple SQL statements in one execute.

Practice

(1/5)
1. What is the main purpose of using parameterized queries in Flask when working with databases?
easy
A. To speed up database queries by caching results
B. To prevent SQL injection attacks by separating code from data
C. To allow users to write their own SQL commands
D. To automatically create database tables

Solution

  1. Step 1: Understand SQL injection risk

    SQL injection happens when user input is treated as code, allowing attackers to change database commands.
  2. Step 2: Role of parameterized queries

    Parameterized queries keep user data separate from SQL code, stopping attackers from injecting harmful commands.
  3. Final Answer:

    To prevent SQL injection attacks by separating code from data -> Option B
  4. Quick Check:

    SQL injection prevention = parameterized queries [OK]
Hint: Remember: separate data from code to stop injection [OK]
Common Mistakes:
  • Thinking parameterized queries speed up queries
  • Believing users can safely write SQL commands
  • Confusing parameterized queries with table creation
2. Which of the following is the correct way to use parameterized queries with Flask's database cursor?
easy
A. cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
B. cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
C. cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
D. cursor.execute("SELECT * FROM users WHERE id = :id", user_id)

Solution

  1. Step 1: Identify correct placeholder syntax

    In Flask with many DB adapters like psycopg2, %s is used as placeholder for parameters.
  2. Step 2: Check parameter passing format

    Parameters must be passed as a tuple, e.g., (user_id,). cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) uses %s and tuple correctly.
  3. Final Answer:

    cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) -> Option C
  4. Quick Check:

    Use %s with tuple for parameters [OK]
Hint: Use %s and tuple for parameters in execute() [OK]
Common Mistakes:
  • Using f-strings directly with user input
  • Using ? placeholder which is for SQLite, not psycopg2
  • Passing parameters incorrectly without tuple
3. Given this Flask code snippet, what will be the output if user_id = "1 OR 1=1" and parameterized queries are used correctly?
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
results = cursor.fetchall()
print(results)
medium
A. Only rows where id equals the string '1 OR 1=1' will be returned
B. All rows from users table will be returned
C. Syntax error due to SQL injection
D. No rows will be returned because of wrong query

Solution

  1. Step 1: Understand parameterized query effect

    Parameterized queries treat user input as data, not code, so "1 OR 1=1" is a string value, not SQL logic.
  2. Step 2: Result of query with injected string

    The query looks for rows where id equals the string "1 OR 1=1", which likely matches no rows or only exact matches.
  3. Final Answer:

    Only rows where id equals the string '1 OR 1=1' will be returned -> Option A
  4. Quick Check:

    Parameterized input treated as data = Only rows where id equals the string '1 OR 1=1' will be returned [OK]
Hint: Parameterized input is data, not code, so no injection [OK]
Common Mistakes:
  • Assuming injection runs and returns all rows
  • Expecting syntax error from parameterized query
  • Thinking query fails due to input format
4. Identify the error in this Flask code that tries to prevent SQL injection:
user_id = request.args.get('id')
cursor.execute("SELECT * FROM users WHERE id = %s" % user_id)
results = cursor.fetchall()
medium
A. Using wrong placeholder %s instead of ?
B. Missing parentheses in fetchall()
C. Not converting user_id to integer
D. Using string formatting instead of parameterized query

Solution

  1. Step 1: Check how query is constructed

    The code uses string formatting (% operator) to insert user_id directly into the query string.
  2. Step 2: Why this is wrong for injection prevention

    Direct string formatting allows malicious input to change SQL code, causing SQL injection risk.
  3. Final Answer:

    Using string formatting instead of parameterized query -> Option D
  4. Quick Check:

    Use parameterized queries, not string formatting [OK]
Hint: Never build queries with string formatting; use parameters [OK]
Common Mistakes:
  • Thinking fetchall() needs parentheses fix
  • Believing user_id must be int for injection safety
  • Confusing %s and ? placeholders
5. You want to safely insert multiple user records into a database using Flask and prevent SQL injection. Which approach correctly combines parameterized queries with batch insertion?
users = [("alice", 25), ("bob", 30)]
cursor.executemany(??? , users)
What should replace ????
hard
A. "INSERT INTO users (name, age) VALUES (%s, %s)"
B. "INSERT INTO users (name, age) VALUES ('%s', '%s')"
C. "INSERT INTO users (name, age) VALUES (?, ?)"
D. "INSERT INTO users (name, age) VALUES (:name, :age)"

Solution

  1. Step 1: Identify correct placeholder syntax for batch insert

    For executemany with psycopg2 or similar, %s placeholders are used without quotes.
  2. Step 2: Check placeholder usage in options

    "INSERT INTO users (name, age) VALUES (%s, %s)" uses %s placeholders correctly; "INSERT INTO users (name, age) VALUES ('%s', '%s')" wrongly adds quotes, "INSERT INTO users (name, age) VALUES (?, ?)" uses ? (SQLite style), "INSERT INTO users (name, age) VALUES (:name, :age)" uses named placeholders which need dicts.
  3. Final Answer:

    "INSERT INTO users (name, age) VALUES (%s, %s)" -> Option A
  4. Quick Check:

    Use %s placeholders without quotes for executemany [OK]
Hint: Use %s placeholders without quotes for batch inserts [OK]
Common Mistakes:
  • Adding quotes around %s placeholders
  • Using ? placeholders with psycopg2
  • Using named placeholders without dict parameters
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard