SQL Injection
SQL Injection
SQL Injection is a security vulnerability that occurs when untrusted input is included directly in SQL queries. Attackers can manipulate the query to read, modify, or delete data.
How SQL Injection Happens
Injection usually happens when user input (for example, from GET/POST) is concatenated into a SQL string.
Unsafe Example (Do Not Use)
$email = $_GET['email']; $sql = "SELECT * FROM users WHERE email = '" . $email . "'"; $result = mysqli_query($conn, $sql);
If an attacker provides a crafted value, they may change the meaning of the query.
Common Attack Example
For example, an attacker might try to inject something like:
' OR '1'='1
If inserted into an unsafe query, it can cause the WHERE clause to always be true.
How to Prevent SQL Injection
- Use parameterized queries (prepared statements)
- Validate and sanitize input (as an extra layer)
- Use least-privilege database users
- Do not expose database errors to users
Safe Example (mysqli Prepared Statements)
$email = $_GET['email']; $stmt = mysqli_prepare($conn, "SELECT id, name, email FROM users WHERE email = ?"); mysqli_stmt_bind_param($stmt, "s", $email); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt);
In this approach, the SQL and the data are handled separately, so user input cannot break the query structure.
Safe Example: Login Check
$email = $_POST['email'];
$password = $_POST['password'];
$stmt = mysqli_prepare($conn, "SELECT id, password_hash FROM users WHERE email = ?");
mysqli_stmt_bind_param($stmt, "s", $email);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
if ($row) {
// Verify password using password_verify() in PHP
}
Input Validation Still Matters
Prepared statements block injection, but validation improves data quality. For example, validate email format before querying.
Limit Database Privileges
Your application should connect with a database user that has only the permissions it needs (for example, no DROP privileges in production).
Error Handling
Do not show raw SQL errors to users. Log errors internally and display a generic message to the user.
Common Mistakes
- Escaping strings manually and thinking it is enough (prepared statements are better)
- Building dynamic SQL with user input without parameters
- Using admin/root database users for the website
Next Step
Continue with SQL Hosting to learn common considerations for running SQL databases in production environments.