01Summary

SQL injection occurs when an application constructs database queries by concatenating user input directly into SQL commands without proper sanitization or parameterization. An attacker can inject malicious SQL syntax to alter the query's logic, bypass authentication, extract unauthorized data, or modify/delete records. This is one of the most common and dangerous web application vulnerabilities.

02How It Happens

When an application builds SQL queries by string concatenation or simple string replacement, it treats user-supplied data as executable SQL code rather than as data. If the input contains SQL metacharacters (like single quotes, semicolons, or SQL keywords), the attacker can "break out" of the intended query structure and append or modify SQL commands. The vulnerability exists because the application does not distinguish between the query's static structure (written by the developer) and the dynamic data (supplied by the user). Even simple escaping functions are often insufficient, as they can be bypassed with encoding tricks or database-specific syntax variations.

03Real-World Impact

SQL injection can lead to complete compromise of a database. An attacker may extract sensitive data (usernames, passwords, personal information, financial records), bypass login mechanisms by manipulating WHERE clauses, modify or delete records, or in some database configurations, execute operating system commands on the server. The impact ranges from data theft and privacy violations to business disruption and regulatory fines.

04Vulnerable & Fixed Patterns

Vulnerable pattern
import sqlite3

def get_user(username):
    conn = sqlite3.connect('app.db')
    cursor = conn.cursor()
    # Directly concatenating user input into the query
    query = "SELECT * FROM users WHERE username = '" + username + "'"
    cursor.execute(query)
    return cursor.fetchone()

# An attacker could pass: admin' OR '1'='1
# This would return all users instead of a specific one

Why it's vulnerable:
The username parameter is concatenated directly into the SQL string. An attacker can inject SQL syntax (e.g., ' OR '1'='1) to alter the query's logic and bypass intended restrictions.

Fixed pattern
import sqlite3

def get_user(username):
    conn = sqlite3.connect('app.db')
    cursor = conn.cursor()
    # Use parameterized query with placeholder
    query = "SELECT * FROM users WHERE username = ?"
    cursor.execute(query, (username,))
    return cursor.fetchone()
Vulnerable pattern
<?php
$username = $_GET['username'];
$mysqli = new mysqli('localhost', 'user', 'password', 'database');

// Directly interpolating user input into the query
$query = "SELECT * FROM users WHERE username = '" . $username . "'";
$result = $mysqli->query($query);
$user = $result->fetch_assoc();
?>

Why it's vulnerable:
The $_GET['username'] variable is directly embedded in the SQL string. An attacker can inject SQL metacharacters to manipulate the query structure.

Fixed pattern
<?php
$username = $_GET['username'];
$mysqli = new mysqli('localhost', 'user', 'password', 'database');

// Use prepared statement with bound parameters
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
?>

05Prevention Checklist

Use parameterized queries (prepared statements)
for all database interactions; never concatenate or interpolate user input into SQL strings.
Apply input validation
to reject unexpected data types, lengths, or formats before they reach the database layer.
Apply the principle of least privilege
to database accounts; use separate credentials with minimal permissions for different application functions.
Use an ORM or query builder
that abstracts SQL construction and enforces parameterization by default.
Enable SQL error suppression
in production; do not display raw database error messages to users, as they can reveal schema information.
Conduct code review and security testing
specifically for SQL injection; use static analysis tools and penetration testing to identify vulnerable patterns.

06Signs You May Already Be Affected

Check your application logs for unusual SQL syntax in query strings, unexpected database errors, or repeated failed login attempts with suspicious characters (quotes, semicolons, SQL keywords). Review database access logs for queries that retrieve or modify unexpected volumes of data, or for administrative operations from non-administrative user accounts. Unexpected new user accounts or privilege escalations in your database may also indicate a successful injection attack.

07Related Recent Vulnerabilities