By now you've probably heard a lot about SQL injection, whether from studying for certificate exams or just as part of your coursework. If you haven't yet encountered it, this article will bring you up to speed on one of the most persistent and dangerous web application vulnerabilities.

What is SQL Injection?

SQL Injection (SQLi) is a code injection technique that exploits security vulnerabilities in an application's database layer. When user input is improperly sanitized and directly concatenated into SQL queries, attackers can inject malicious SQL commands that the database will execute.

Quick Example

Consider a login form where a user enters their username. A vulnerable application might construct a query like:

SELECT * FROM Users WHERE username = 'admin' AND password = 'password123'

An attacker could enter admin' OR '1'='1'-- as the username, resulting in:

SELECT * FROM Users WHERE username = 'admin' OR '1'='1'--' AND password = ''

This query always returns true, bypassing authentication entirely.

OWASP Top 10 and SQL Injection

SQL Injection consistently appears in the OWASP Top 10, currently listed under A03:2021 – Injection. Despite being well-understood for decades, it remains prevalent because:

  • Legacy applications still use vulnerable code patterns
  • Developers may not understand secure coding practices
  • Dynamic SQL construction without proper parameterization
  • Insufficient input validation on user-supplied data

Which Applications Are Affected?

Any web application that interacts with a SQL database is potentially vulnerable if it:

  • Accepts user input through forms, URL parameters, or APIs
  • Constructs SQL queries using string concatenation
  • Fails to properly validate or sanitize input
  • Uses dynamic SQL without parameterized queries

Common vulnerable applications include e-commerce platforms, content management systems, customer portals, and any web application with login functionality or search features.

How SQL Injection Works: Client Side

Vulnerable Input Fields

SQL injection can occur in any input field that's used in database queries:

  • Login forms - Username and password fields
  • Search boxes - Product or content search
  • URL parameters - GET requests with query strings
  • Form fields - Registration, profile updates, comments
  • HTTP headers - User-Agent, Referer, cookies

Testing for SQL Injection

From the client side, you can test for SQL injection by entering special characters and SQL syntax:

' (single quote)
'' (two single quotes)
; (semicolon)
-- (SQL comment)
' OR '1'='1
' OR '1'='1'--
' UNION SELECT NULL--

If the application returns database errors or behaves unexpectedly, it may be vulnerable.

Server-Side Behavior

How the Server Interprets Malicious Input

When vulnerable code concatenates user input directly into SQL queries, the database cannot distinguish between legitimate SQL commands and malicious injection. For example:

// Vulnerable PHP Code
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM Users WHERE username = '$username' AND password = '$password'";
$result = mysqli_query($conn, $query);

If a user inputs admin' OR '1'='1'--, the resulting query becomes:

SELECT * FROM Users WHERE username = 'admin' OR '1'='1'--' AND password = ''

Server Response and Database Errors

Vulnerable applications may reveal critical information through error messages:

  • Database type and version
  • Table and column names
  • File system paths
  • Query structure details

Tracking in Audit Logs

Database audit logs can capture SQL injection attempts. In Azure SQL Database and SQL Server, enable auditing to log:

  • Failed login attempts with unusual characters
  • Queries with unexpected UNION, SELECT, or DROP statements
  • Queries accessing system tables like information_schema
  • Multiple rapid-fire query attempts (indicative of automated scanning)

Regular log review helps identify attack patterns and compromised endpoints before significant damage occurs.

Impact on the CIA Triad

Confidentiality

SQL injection can expose sensitive data including:

  • User credentials (usernames, password hashes)
  • Personal identifiable information (PII)
  • Payment card data (violates PCI DSS)
  • Proprietary business information
  • Database structure and schema details

Integrity

Attackers can modify database contents:

  • Altering user account details (privilege escalation)
  • Modifying product prices or inventory
  • Injecting malicious content into stored data
  • Tampering with audit logs to cover tracks

Availability

Database operations can be disrupted:

  • Dropping critical tables (DROP TABLE Users)
  • Resource exhaustion through complex queries
  • Database server crashes
  • Denial of service attacks

Business Impact of SQL Injection

Financial Consequences

Using risk assessment methodologies, we can quantify SQLi impact:

  • Data Breach Costs - Notification requirements, forensic investigation, legal fees
  • Regulatory Fines - PCI DSS violations can result in fines up to $500,000
  • Business Disruption - Downtime during incident response and recovery
  • Reputation Damage - Loss of customer trust and future revenue

Example Calculation:

For an e-commerce application valued at $3M with 90% exposure factor:

  • Single Loss Expectancy (SLE) = $3M × 0.90 = $2.7M
  • Annual Rate of Occurrence (ARO) = 2.4 attacks/year
  • Annual Loss Expectancy (ALE) = $2.7M × 2.4 = $6.5M

How to Combat SQL Injection

1. Parameterized Queries (Prepared Statements)

The most effective defense is using parameterized queries where SQL code and data are separated:

// Secure PHP Code with Prepared Statements
$stmt = $conn->prepare("SELECT * FROM Users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
$result = $stmt->get_result();

The database treats parameter values as data only—never as executable SQL commands. The ? placeholders ensure that user input cannot alter query structure.

2. Input Validation

Validate all user input against expected patterns:

  • Whitelist validation - Only allow known-good characters
  • Data type enforcement - Ensure integers are integers, emails match format
  • Length restrictions - Limit input to expected sizes
  • Encoding - Properly encode special characters
// Input Validation Example
if (!preg_match("/^[a-zA-Z0-9_]{3,20}$/", $username)) {
    die("Invalid username format");
}

$user_id = (int)$_GET['id']; // Type casting to integer

3. Principle of Least Privilege

Database accounts used by applications should have minimal necessary permissions:

  • No DROP, CREATE, or ALTER permissions
  • Read-only access where possible
  • Limited to specific tables and procedures
  • Separate accounts for different application functions

4. Web Application Firewalls (WAF)

Implement WAF rules to detect and block SQL injection attempts:

  • Pattern matching for common SQLi payloads
  • Rate limiting to prevent automated attacks
  • Logging and alerting on suspicious patterns

5. Error Handling

Never expose detailed database errors to users:

// Bad - Exposes database details
catch (Exception $e) {
    echo $e->getMessage();
}

// Good - Generic error message
catch (Exception $e) {
    error_log($e->getMessage());
    echo "An error occurred. Please try again.";
}

Why Defense in Depth Matters

While parameterized queries effectively prevent SQL injection, relying on a single control is risky:

Layered Security Approach

  1. Secure coding practices - Parameterized queries and input validation
  2. Database security - Least privilege, encryption at rest
  3. Network controls - WAF, network segmentation
  4. Monitoring - Audit logging, SIEM alerts
  5. Incident response - Detection and response procedures

If one layer fails, others provide backup protection.

Testing for SQL Injection

As a security professional, you should be able to identify SQLi vulnerabilities:

Manual Testing Techniques

  • Error-based detection (entering ' to trigger errors)
  • Boolean-based testing (' OR '1'='1)
  • UNION-based injection (enumerating database structure)
  • Time-based blind SQLi (using SLEEP() or WAITFOR)

Automated Scanning Tools

Tools that help identify SQL injection vulnerabilities:

  • SQLMap - Automated SQL injection and database takeover tool
  • Burp Suite - Web application security testing platform
  • OWASP ZAP - Open-source web application scanner
  • Wapiti - Web application vulnerability scanner

Key Takeaways

  • SQL injection remains a critical threat despite being well-understood
  • Always use parameterized queries—never concatenate user input into SQL
  • Implement input validation as an additional layer of defense
  • Apply principle of least privilege to database accounts
  • Monitor audit logs for attack patterns
  • Understand the business impact to justify security investments
  • Practice testing techniques in legal, controlled environments

Further Learning

Ready to practice? Check out these resources:

Legal Reminder

Only test for vulnerabilities on systems you own or have explicit written permission to test. Unauthorized testing is illegal and unethical. Set up your own lab environment or use intentionally vulnerable applications like DVWA, WebGoat, or Mutillidae for practice.