Second-Order SQL Injection

🔐 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; --';
➡️ The second query causes destructive SQL Injection triggered not at the point of entry, but during a later operation.

🏥 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'; --';
➡️ Insurance status is modified by second-order injection.

🛡️ 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

🧠 Final Note

Second-order SQL injections are harder to detect because they don’t cause immediate symptoms. They often bypass WAFs and input validators. Always treat data from your own database as untrusted, especially if that data was originally entered by users.

Post a Comment

0 Comments