📖 Scenario: You are building a simple PHP script that queries a database for user information based on a username input. This project will show how unsafe SQL queries can be exploited by SQL injection.
🎯 Goal: Create a PHP script that demonstrates an unsafe SQL query vulnerable to SQL injection, then show how an attacker can exploit it by entering a malicious username.
📋 What You'll Learn
Create a variable $username with a sample user input string
Create a variable $query that builds an SQL query string using $username directly
Simulate an attacker input that exploits the unsafe query
Print the final SQL query string to show the injection effect
💡 Why This Matters
🌍 Real World
Web applications often take user input to query databases. If this input is not handled safely, attackers can exploit it to steal or damage data.
💼 Career
Understanding SQL injection is critical for developers and security professionals to build safe applications and protect user data.
Progress0 / 4 steps
1
DATA SETUP: Create a user input variable
Create a variable called $username and set it to the string 'alice' to simulate a normal user input.
PHP
Hint
Use $username = 'alice'; to store the username.
2
CONFIGURATION: Build an unsafe SQL query string
Create a variable called $query that builds an SQL query string by directly inserting the $username variable inside the query without any safety measures. Use double quotes and write: SELECT * FROM users WHERE username = '$username'.
PHP
Hint
Use double quotes and insert $username inside single quotes in the query string.
3
CORE LOGIC: Simulate an attacker input exploiting SQL injection
Change the $username variable to the string 'alice' OR '1'='1' to simulate an attacker input that exploits the unsafe query.
PHP
Hint
Set $username to "alice' OR '1'='1" including the quotes inside the string.
4
OUTPUT: Print the final SQL query string
Write a print statement to display the value of the $query variable.
PHP
Hint
Use print($query); to show the final query string.
Practice
(1/5)
1. What is the main risk of using unsafe SQL queries in PHP without proper input handling?
easy
A. The website will load faster
B. Users will see more colorful pages
C. Attackers can insert harmful SQL commands to access or damage the database
D. The server will automatically block all users
Solution
Step 1: Understand unsafe SQL queries
Unsafe queries allow user input directly in SQL commands without checks.
Step 2: Identify the risk of SQL injection
This lets attackers add harmful commands to steal or change data.
Final Answer:
Attackers can insert harmful SQL commands to access or damage the database -> Option C
Quick Check:
Unsafe queries = SQL injection risk [OK]
Hint: Unsafe queries let attackers add harmful commands [OK]
Common Mistakes:
Thinking unsafe queries improve speed
Confusing SQL injection with visual changes
Assuming server blocks all users automatically
2. Which PHP code snippet is unsafe and vulnerable to SQL injection?
easy
A. $query = "SELECT * FROM users WHERE name = '" . $_GET['name'] . "'";
B. $stmt = $pdo->prepare('SELECT * FROM users WHERE name = ?'); $stmt->execute([$_GET['name']]);
C. $stmt = $pdo->prepare('SELECT * FROM users WHERE name = :name'); $stmt->execute(['name' => $_GET['name']]);
D. $query = 'SELECT * FROM users WHERE name = :name'; $stmt = $pdo->prepare($query); $stmt->execute(['name' => 'Alice']);
Solution
Step 1: Identify direct user input in query string
$query = "SELECT * FROM users WHERE name = '" . $_GET['name'] . "'"; directly inserts $_GET['name'] into the SQL string without protection.
Step 2: Compare with prepared statements
Options A, B, and D use prepared statements which safely handle input.
Final Answer:
$query = "SELECT * FROM users WHERE name = '" . $_GET['name'] . "'"; -> Option A
Quick Check:
Direct input in query = unsafe [OK]
Hint: Directly adding user input to query is unsafe [OK]
Common Mistakes:
Confusing prepared statements with unsafe queries
Thinking all string concatenations are safe
Ignoring the use of placeholders in queries
3. What will be the output of this PHP code if the URL parameter is ?id=1 OR 1=1?
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
echo $query;
medium
A. SELECT * FROM users WHERE id = 1
B. SELECT * FROM users WHERE id = 1 OR 1=1
C. Syntax error in SQL query
D. SELECT * FROM users WHERE id = '1 OR 1=1'
Solution
Step 1: Substitute the URL parameter into the query
The variable $id becomes the string "1 OR 1=1" directly inserted into the query.
Step 2: Form the final SQL query string
The query becomes: SELECT * FROM users WHERE id = 1 OR 1=1, which is a valid SQL statement.
Final Answer:
SELECT * FROM users WHERE id = 1 OR 1=1 -> Option B
Quick Check:
Unsafe input inserted directly = query with injected condition [OK]
Hint: Direct input inserts raw text into query [OK]
Common Mistakes:
Assuming input is automatically quoted
Expecting syntax error without quotes
Ignoring how SQL interprets OR conditions
4. Identify the error in this PHP code that makes it vulnerable to SQL injection:
$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
$result = mysqli_query($conn, $query);
medium
A. The query string is missing a semicolon
B. The variable $username is not defined
C. mysqli_query cannot run SELECT queries
D. Using prepared statements would prevent SQL injection
Solution
Step 1: Check how user input is used in the query
The variable $username is inserted directly into the SQL string without sanitization.
Step 2: Suggest the fix to prevent injection
Using prepared statements safely handles input and prevents injection attacks.
Final Answer:
Using prepared statements would prevent SQL injection -> Option D
Quick Check:
Direct input in query = vulnerability [OK]
Hint: Use prepared statements to fix injection bugs [OK]
Common Mistakes:
Thinking variable is undefined
Believing mysqli_query can't run SELECT
Focusing on missing semicolon instead of security
5. You want to fix this vulnerable PHP code to prevent SQL injection:
$email = $_POST['email'];
$query = "SELECT * FROM users WHERE email = '$email'";
$result = mysqli_query($conn, $query);
Which is the best way to fix it?
hard
A. $stmt = $conn->prepare('SELECT * FROM users WHERE email = ?'); $stmt->bind_param('s', $email); $stmt->execute();
B. $email = addslashes($_POST['email']); $query = "SELECT * FROM users WHERE email = '$email'"; mysqli_query($conn, $query);
C. $query = "SELECT * FROM users WHERE email = '" . $_POST['email'] . "'"; mysqli_query($conn, $query);
D. $email = htmlspecialchars($_POST['email']); $query = "SELECT * FROM users WHERE email = '$email'"; mysqli_query($conn, $query);
Solution
Step 1: Review each option's security
$stmt = $conn->prepare('SELECT * FROM users WHERE email = ?'); $stmt->bind_param('s', $email); $stmt->execute(); uses prepared statements with parameter binding, which safely handles input.
Step 2: Compare other options
$email = addslashes($_POST['email']); $query = "SELECT * FROM users WHERE email = '$email'"; mysqli_query($conn, $query); uses addslashes which is not fully safe; C is unsafe direct insertion; D uses htmlspecialchars which is for HTML, not SQL.
Final Answer:
$stmt = $conn->prepare('SELECT * FROM users WHERE email = ?'); $stmt->bind_param('s', $email); $stmt->execute(); -> Option A
Quick Check:
Prepared statements = best SQL injection protection [OK]
Hint: Use prepared statements with bind_param for safety [OK]
Common Mistakes:
Relying on addslashes for security
Using htmlspecialchars for SQL input
Continuing direct string concatenation
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.