GO KALI FREE
IntermediateWeb Security

SQL Injection Basics: Understanding and Preventing Database Attacks

Learn how SQL injection attacks work, how to test for them, and how to prevent them in your web applications using parameterized queries and other defenses.

#SQL Injection#Database Security#Web Security#OWASP#Penetration Testing

When a Text Box Drains the Database

A text box on a login page. The attacker types: ' OR 1=1 --. The database returns every user row. This is SQL Injection (SQLi) — the most damaging web application vulnerability of the past two decades. When user input is included directly in SQL queries without sanitization, attackers can read, modify, or delete your entire database.

Impact of SQL Injection

The consequences of a successful SQL injection attack can be devastating:

  • **Data Breach**: Unauthorized access to sensitive data including passwords, personal information, and financial records
  • **Data Loss**: Deletion of entire database tables
  • **Data Corruption**: Modification of data integrity
  • **Authentication Bypass**: Accessing restricted areas without valid credentials
  • **Privilege Escalation**: Gaining administrative access to the database
  • **Remote Code Execution**: In severe cases, full compromise of the database server
  • Types of SQL Injection

    In-band SQL Injection

    The attacker uses the same channel to inject code and retrieve results. This is the most common and straightforward type.

    Error-based SQLi: Relies on error messages from the database to gather information about its structure. For example, intentionally causing type errors reveals column names and data types.

    Union-based SQLi: Uses the UNION SQL operator to combine results from multiple queries, extracting data from other tables. The attacker must match the number of columns in the original query.

    Blind SQL Injection

    The attacker cannot see direct query results but can infer information based on the application's behavior.

    Boolean-based Blind SQLi: Sends queries that return true or false and observes differences in application responses. For example, checking if a character in a password is greater than a specific value.

    Time-based Blind SQLi: Uses database time delay functions like SLEEP() or WAITFOR to infer information based on response times. A delayed response confirms the condition was true.

    Out-of-band SQL Injection

    The attacker uses a different channel to receive data, such as DNS or HTTP requests. This is used when the application does not display query results or error messages.

    How SQL Injection Works

    Vulnerable Code Example

    Consider a login form that builds a query by directly concatenating user input:

    $query = "SELECT * FROM users WHERE username = '" . $_POST['username'] . "' AND password = '" . $_POST['password'] . "'";
    

    When an attacker enters admin' -- as the username, the query becomes:

    SELECT * FROM users WHERE username = 'admin' --' AND password = ''
    

    The -- comments out the password check, allowing authentication as admin without knowing the password.

    Data Extraction with UNION

    ' UNION SELECT username, password FROM users --
    

    This adds the contents of the users table to the query results, potentially exposing all credentials.

    Blind Injection Example

    Time-based detection in MySQL:

    ' OR IF(1=1, SLEEP(5), 0) --
    

    If the response takes 5 seconds, SQL injection is confirmed.

    Detection and Testing

    Manual Testing Indicators

    Look for inputs such as search fields, login forms, URL parameters, and API endpoints. Test with simple payloads:

  • Single quote: `'`
  • SQL comments: `--`,`#`
  • Boolean tests: `' OR '1'='1`, `' AND '1'='0`
  • Time delays: `' OR SLEEP(5)--`
  • Automated Tools

    SQLMap is the most popular automated SQL injection tool:

    # Basic scan
    sqlmap -u "http://example.com/page?id=1" --batch
    
    # Enumerate databases
    sqlmap -u "http://example.com/page?id=1" --dbs
    
    # Extract tables
    sqlmap -u "http://example.com/page?id=1" -D database --tables
    
    # Dump data
    sqlmap -u "http://example.com/page?id=1" -D database -T users --dump
    

    {@visual sqlmap-exploit-output}

    Prevention Techniques

    Parameterized Queries (Prepared Statements)

    The most effective defense. Placeholders separate SQL code from user data:

    cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))
    

    Stored Procedures

    Use pre-compiled stored procedures instead of dynamic SQL:

    CREATE PROCEDURE GetUser @Username nvarchar(50)
    AS
    SELECT * FROM users WHERE username = @Username
    

    Input Validation and Output Encoding

  • Validate input types (numeric, email, alphanumeric)
  • Whitelist allowed characters
  • Reject suspicious SQL patterns
  • Encode output to prevent secondary injection
  • Least Privilege

  • Database accounts should have minimum necessary permissions
  • Application accounts should not have DDL permissions
  • Separate read and write accounts
  • Web Application Firewall (WAF)

    WAFs can detect and block SQL injection attempts based on known patterns.

    Database-Specific Considerations

    MySQL: Comments with -- and #, information schema in information_schema, version with @@version

    PostgreSQL: Comments with --, supports stacked queries with ;

    MSSQL: Comments with --, system tables in sys.tables, dangerous extended procedures like xp_cmdshell

    Oracle: Comments with --, uses dual table, string concatenation with ||

    SQL injection remains a critical threat despite being well-understood. Using parameterized queries, validating input, and conducting regular security testing can eliminate this vulnerability from your applications.

    References

    {@ref owasp-top10}

    {@ref owasp-testing-guide}

    Frequently Asked Questions

    What is SQL injection and how does it work?

    SQL injection is a vulnerability where attackers insert malicious SQL code into input fields to manipulate database queries. It works when user input is directly concatenated into SQL statements without proper sanitization, allowing attackers to extract, modify, or delete data.

    How do I test for SQL injection vulnerabilities?

    Start by inserting single quotes, SQL comments (--), and boolean conditions like ' OR '1'='1 into input fields. Use automated tools like [SQLMap](/tools/sqlmap) for comprehensive testing. Look for database error messages in responses, which often indicate vulnerable inputs.

    What is the difference between in-band and blind SQL injection?

    In-band SQL injection returns results directly in the application response (error-based or union-based). Blind SQL injection does not return visible results — instead, attackers infer information from application behavior changes or time delays like SLEEP() functions.

    Can SQL injection affect NoSQL databases?

    Yes, NoSQL databases like MongoDB and CouchDB are also vulnerable to injection attacks, though the syntax differs. MongoDB injection typically targets JavaScript-based queries. Use parameterized queries and input validation specific to your database technology.

    How do parameterized queries prevent SQL injection?

    Parameterized queries separate SQL code from user data by using placeholders. The database engine treats user input as data, not executable code, making it impossible for injected SQL to alter the query logic. Always use prepared statements in Python, PHP, Java, and other languages.

    What is SQLMap and how do I use it?

    SQLMap is an open-source automated SQL injection tool that detects and exploits vulnerabilities across multiple database systems. Use it with `sqlmap -u "http://example.com/page?id=1" --batch` for basic scans. Add `--dbs` to enumerate databases and `--dump` to extract data. Always get authorization before scanning.

    Are stored procedures safe from SQL injection?

    Stored procedures reduce but do not eliminate SQL injection risk. If stored procedures dynamically construct SQL with string concatenation, they remain vulnerable. Use parameterized stored procedures and validate all input even when using them.

    How does input validation help prevent SQL injection?

    Input validation acts as a defense-in-depth layer by rejecting unexpected input patterns. Whitelist allowed characters, validate data types (numeric fields should only accept numbers), and enforce length limits. Combine validation with parameterized queries for strongest protection.

    What database-specific SQL injection techniques should I know?

    MySQL uses `--` and `#` comments with `information_schema` for enumeration. PostgreSQL supports stacked queries with `;`. MSSQL has dangerous procedures like `xp_cmdshell`. Oracle uses the `dual` table. Each database requires different exploitation and [defense strategies](/learn/web-security-fundamentals).

    Can a Web Application Firewall prevent SQL injection?

    WAFs can detect and block many common SQL injection patterns, but determined attackers can often bypass them using encoding tricks and evasion techniques. WAFs should be one layer in a defense-in-depth strategy, not the primary protection. Always implement parameterized queries at the application layer.