🔐 What is Second Order SQL Injection?
In a second-order SQL injection, the attacker injects malicious input that is stored by the application (like in a user profile). When this stored data is used later (e.g., in a SQL query without re-sanitization), it results in SQL injection.
✅ Key Characteristics
- Payload is stored in the application (often via a trusted path).
- Execution happens later, possibly in a different module.
- Can bypass input validation if validation is applied only at the time of entry.
📘 Real-World Example: Web Application with User Registration and Admin Search
💥 Scenario
A web application allows users to register, and the admin panel provides functionality to search users by name.
1. 🖊️ Registration Form:
INSERT INTO users (username, email, password)
VALUES ('$username', '$email', '$password');
Attacker registers with the following name:
username = mike'; DROP TABLE users; --
This input is stored safely in the users table without error because input is sanitized or parameterized at this stage.
2. 🕵️ Admin Panel - Search Feature:
Admin searches for users by typing a name. The backend forms a query like:
SELECT * FROM users WHERE username = '$search_term';
If the admin inputs nothing and clicks "Search All", the app may do:
SELECT * FROM users WHERE username LIKE '%$search_term%';
Now, when this query is run with the value from the database (e.g., mike'; DROP TABLE users; --), it becomes:
SELECT * FROM users WHERE username = 'mike'; DROP TABLE users; --';
🏥 Healthcare App Example
A patient signs up with a crafted medical history:
allergies = penicillin'; UPDATE patients SET insurance = 'Gold' WHERE name = 'John'; --
Initially, this input is stored harmlessly.
Later, during a batch processing report that builds SQL like:
SELECT * FROM patients WHERE allergies = '$allergies';
It executes:
SELECT * FROM patients WHERE allergies = 'penicillin'; UPDATE patients SET insurance = 'Gold' WHERE name = 'John'; --';
🛡️ How to Prevent Second-Order SQL Injection
- Use Parameterized Queries (Prepared Statements) everywhere—even when data comes from your own database.
- Validate & Sanitize Inputs both on entry and usage.
- Escape Data Appropriately when injecting into queries (though prefer parameterized queries over escaping).
- Audit Stored Data that could be used in dynamic queries later.
- Secure All Query Contexts:
- Logging queries
- Report generation
- Audit modules

0 Comments