-
Notifications
You must be signed in to change notification settings - Fork 0
Module: SQL‐Injection
Module Name: sql_injection
Requires Sink: SQLite
SQL injection is a code injection that exploits vulnerabilities in applications that use user input to construct SQL queries. Attackers can manipulate queries to access, modify or delete data, bypass authentication or even execute system commands in some cases.
This module creates a real SQL injection vulnerability by executing user-supplied input directly against an in-memory SQLite database.
The sql_injection module supports the following placements (it can extract input from these places):
| Placement | Description | Example Request |
|---|---|---|
query param |
URL query string | GET /users?id=1 |
path_param |
URL path segment | GET /user/1 |
form_field |
POST form data |
POST /login with username=admin
|
json_field |
JSON body field |
POST /api/users with {"id": 1}
|
header |
HTTP header | X-User-Id: 1 |
cookie |
Cookie value | Cookie: user_id=1 |
This defines the type of SQL injection behavior. It determines how results are returned.
| Value | Description | Use Case |
|---|---|---|
error_based |
Returns query results and SQL errors | Testing error-based detection |
blind_boolean |
Returns only success/failure | Testing blind boolean injection |
Default:
error_based
This is the SQL query template to be executed by the application using the input.
-
{input}is used as a placeholder for user input.
query_template: "SELECT * FROM users WHERE id = {input}"The {input} placeholder is replaced with the user's input without sanitization.
Examples
# Numeric injection point
query_template: "SELECT * FROM users WHERE id = {input}"
# String injection point (quotes)
query_template: "SELECT * FROM users WHERE username = '{input}'"
# LIKE clause
query_template: "SELECT * FROM products WHERE name LIKE '%{input}%'"
# Multiple columns
query_template: "SELECT * FROM users WHERE username = '{input}' AND active = 1"This is used to configure whether to include SQL error messages in the response.
| Value | Behavior |
|---|---|
true |
SQL errors are included in response (useful for error-based injection) |
false |
Generic "Database error" message returned |
Default:
true
These are intentionally weak input filtering. They are bypassable protections that can be tested against.
| Value | Description | Bypass Method |
|---|---|---|
none |
No filtering (fully vulnerable) | N/A |
basic_quotes |
Escapes single quotes (' → '') |
use numeric type in query |
remove_comments |
Removes SQL comments | Alternative comment syntax |
Default:
none
sql_injection module requires the data section in the config to define tables.
data:
tables:
TABLE_NAME:
columns: [COL1, COL2, COL3, COL4, COL5]
rows:
- [COL1_ENTRY, COL2_ENTRY, COL3_ENTRY, COL4_ENTRY, COL5_ENTRY]
- [COL1_ENTRY, COL2_ENTRY, COL3_ENTRY, COL4_ENTRY, COL5_ENTRY]
- [COL1_ENTRY, COL2_ENTRY, COL3_ENTRY, COL4_ENTRY, COL5_ENTRY]Example:
data:
tables:
users:
columns: [id, username, password, email, role]
rows:
- [1, "admin", "supersecret", "admin@example.com", "admin"]
- [2, "john", "password123", "john@example.com", "user"]
- [3, "jane", "jane2024", "jane@example.com", "user"]The above data section creates a users table with 5 columns: id, username, password, email, role and adds 3 rows to it.
note: All columns are created as TEXT type. The values provided are stored as-is (no type conversion). Additionally, the tables are created fresh on each startup.
app:
name: "SQLi Lab 1"
port: 8081
data:
tables:
users:
columns: [id, username, password, email]
rows:
- [1, "admin", "secret123", "admin@example.com"]
- [2, "user", "password", "user@example.com"]
endpoints:
- path: /users
method: GET
vulnerabilities:
- type: sql_injection
placement: query_param
param: id
config:
variant: error_based
query_template: "SELECT * FROM users WHERE id = {input}"
show_errors: trueapp:
name: "SQLi Lab 2"
port: 8082
data:
tables:
users:
columns: [id, username, password, email]
rows:
- [1, "admin", "secret123", "admin@example.com"]
- [2, "user", "password", "user@example.com"]
endpoints:
- path: /login
method: POST
vulnerabilities:
- type: sql_injection
placement: form_field
param: username
config:
variant: error_based
query_template: "SELECT * FROM users WHERE username = '{input}' AND password = 'anything'"
show_errors: trueapp:
name: "SQLi Lab 3"
port: 8083
data:
tables:
users:
columns: [id, username, password, email]
rows:
- [1, "admin", "secret123", "admin@example.com"]
- [2, "user", "password", "user@example.com"]
endpoints:
- path: /api/check-user
method: GET
vulnerabilities:
- type: sql_injection
placement: query_param
param: id
config:
variant: blind_boolean
query_template: "SELECT * FROM users WHERE id = {input}"Response behavior:
- If query returns results:
{"success": true, "message": "Record found"} - If query returns no results:
{"success": false, "message": "Record not found"}
app:
name: "SQLi Lab 5"
port: 8085
data:
tables:
users:
columns: [id, username, password, email]
rows:
- [1, "admin", "secret123", "admin@example.com"]
- [2, "user", "password", "user@example.com"]
endpoints:
- path: /user/{id}
method: GET
vulnerabilities:
- type: sql_injection
placement: path_param
param: id
config:
query_template: "SELECT * FROM users WHERE id = {input}"app:
name: "SQLi Lab 6"
port: 8086
data:
tables:
users:
columns: [id, username, password, email]
rows:
- [1, "admin", "secret123", "admin@example.com"]
- [2, "user", "password", "user@example.com"]
endpoints:
- path: /api/search
method: POST
vulnerabilities:
- type: sql_injection
placement: json_field
param: filter.user_id # Supports dot notation
config:
query_template: "SELECT * FROM users WHERE id = {input}"app:
name: "SQLi Lab 7"
port: 8087
data:
tables:
users:
columns: [id, username, password, email]
rows:
- [1, "admin", "secret123", "admin@example.com"]
- [2, "user", "password", "user@example.com"]
endpoints:
- path: /secure/users
method: GET
vulnerabilities:
- type: sql_injection
placement: query_param
param: id
config:
query_template: "SELECT * FROM users WHERE username = '{input}'"
filter: basic_quotes
show_errors: trueTest SQLi from all possible input locations:
app:
name: "SQLi All Placements"
port: 8080
data:
tables:
users:
columns: [id, username, password]
rows:
- [1, "admin", "secret"]
- [2, "user", "pass"]
endpoints:
# Query parameter
- path: /users/query
method: GET
vulnerabilities:
- type: sql_injection
placement: query_param
param: id
config:
query_template: "SELECT * FROM users WHERE id = {input}"
# Path parameter
- path: /users/path/{id}
method: GET
vulnerabilities:
- type: sql_injection
placement: path_param
param: id
config:
query_template: "SELECT * FROM users WHERE id = {input}"
# Form field
- path: /users/form
method: POST
vulnerabilities:
- type: sql_injection
placement: form_field
param: id
config:
query_template: "SELECT * FROM users WHERE id = {input}"
# JSON field
- path: /users/json
method: POST
vulnerabilities:
- type: sql_injection
placement: json_field
param: id
config:
query_template: "SELECT * FROM users WHERE id = {input}"
# Header
- path: /users/header
method: GET
vulnerabilities:
- type: sql_injection
placement: header
param: X-User-Id
config:
query_template: "SELECT * FROM users WHERE id = {input}"
# Cookie
- path: /users/cookie
method: GET
vulnerabilities:
- type: sql_injection
placement: cookie
param: user_id
config:
query_template: "SELECT * FROM users WHERE id = {input}"