SQL Injection has been in the OWASP Top 10 since its first edition in 2003. In 2026 it remains one of the most exploited vulnerabilities in the world. Not because it's hard to prevent — but because many developers still don't know how it really works. This article explains it with real code.
What is SQL Injection?
SQL Injection (SQLi) is a vulnerability that allows an attacker to interfere with the queries an application makes to its database. It occurs when the application includes user data directly into an SQL query without filtering or validating it.
The result: the attacker can read data they shouldn't see, modify it, delete it, or in some cases execute commands on the server.
How it works: the classic login example
Imagine a login form. The PHP code processing the login might look something like this:
$user = $_POST['usuario']; $pass = $_POST['password']; $query = "SELECT * FROM usuarios WHERE usuario = '$user' AND password = '$pass'"; // If it finds results → successful login
If the user types admin and their password, the query becomes:
SELECT * FROM usuarios WHERE usuario = 'admin' AND password = '1234'
So far so good. Now comes the attack. The attacker types this in the username field:
admin' --
The resulting query is:
SELECT * FROM usuarios WHERE usuario = 'admin' --// ' AND password = 'whatever'
The -- comments out everything that follows. The password condition disappears. The attacker logs in as admin without knowing the password.
Types of SQL Injection
The attacker receives the results directly in the web response. It is the easiest to exploit and detect. Includes the Union-based variant (uses UNION to extract data from other tables) and Error-based (gets info from server error messages).
The application does not return data directly, but the attacker can ask yes/no questions based on the web's behavior (if it takes longer to respond, if it shows one result or another). Slower but equally effective.
The attacker extracts data through a different channel (a DNS or HTTP request to a server they control). Less common, but very hard to detect with basic monitoring.
What an attacker can do with SQLi
- →Extract the entire database: users, passwords, customer data, cards.
- →Bypass login without knowing any passwords.
- →Modify or delete data: orders, prices, permissions.
- →In MySQL with FILE permissions: read server files or write webshells.
- →Escalate privileges within the server if the DB runs as root.
How to prevent it properly
1. Prepared statements (the definitive solution)
The correct way to query the previous login using PDO in PHP:
$stmt = $pdo->prepare( "SELECT * FROM usuarios WHERE usuario = ? AND password = ?" ); $stmt->execute([$user, $pass]); // Parameters are never mixed with SQL
// The previous attack does not work
2. Input validation and sanitization
Even if you use prepared statements, always validate the expected type and format. An age field should only accept numbers. An email must have a valid format. Validation does not replace prepared statements — it complements them.
3. Principle of least privilege in the database
The database user your application uses should only have the strictly necessary permissions. If it only needs SELECT and INSERT, don't give it DELETE or DROP. If the attacker exploits an SQLi, the damage is limited.
4. Do not show SQL errors to the user
MySQL error messages contain information that helps the attacker map your database. In production, disable error display and save them in server logs.
Want to know if your website is vulnerable to SQLi?
We use SQLMap and manual tests to detect injections in forms, URLs, and headers. Report with real impact and correction code.
View web audit →