SQL injection usually occurs when you ask a user for input, like their username/userid, and instead of a name/id, the user gives you an SQL statement that you will unknowingly run on your database. Look at the following example which creates a SELECT statement by adding a variable (txtUserId) to a select string.
A SQL injection is a technique that attackers use to gain unauthorized access to a web application database by adding a string of malicious code to a database query. A SQL injection (SQLi) manipulates SQL code to provide access to protected resources, such as sensitive data, or execute malicious SQL statements.
A double query SQL injection is nothing but combining two queries into a single query and getting the information through the SQL error message from the database.
Can someone explain SQL injecton?
SQL injection happens when you interpolate some content into a SQL query string, and the result modifies the syntax of your query in ways you didn't intend.
It doesn't have to be malicious, it can be an accident. But accidental SQL injection is more likely to result in an error than in a vulnerability.
The harmful content doesn't have to come from a user, it could be content that your application gets from any source, or even generates itself in code.
How does it cause vulnerabilities?
It can lead to vulnerabilities because attackers can send values to an application that they know will be interpolated into a SQL string. By being very clever, they can manipulate the result of queries, reading data or even changing data that they shouldn't be allowed to do.
Example in PHP:
$password = $_POST['password'];
$id = $_POST['id'];
$sql = "UPDATE Accounts SET PASSWORD = '$password' WHERE account_id = $id";
Now suppose the attacker sets the POST request parameters to "password=xyzzy
" and "id=account_id
" resulting in the following SQL:
UPDATE Accounts SET PASSWORD = 'xyzzy' WHERE account_id = account_id
Although I expected $id
to be an integer, the attacker chose a string that is the name of the column. Of course now the condition is true on every row, so the attacker has just set the password for every account. Now the attacker can log in to anyone's account -- including privileged users.
Where exactly is the point where SQL is injected?
It isn't SQL that's injected, it's content that's interpolated ("injected") into a SQL string, resulting in a different kind of query than I intended. I trusted the dynamic content without verifying it, and executed the resulting SQL query blindly. That's where the trouble starts.
SQL injection is a fault in the application code, not typically in the database or in the database access library or framework.
Most cases of SQL injection can be avoided by using query parameters. See How can I prevent SQL injection in PHP? for examples.
SQL Injection occurs when the user of an application is able to affect the meaning of database query. This often occurs when arbitary strings from user input are concatenated to create SQL which is fed to the database. For example lets say we had the following code (in PHP, but the same holds true for any language), which might be used to handle a user login.
$sql = "SELECT FROM users WHERE username='".$_GET['username']."' AND password='".$_GET['password']."'";
The harm is done when the user enters something like
administrator'; --
... for the username. Without proper encoding the query becomes:
SELECT * FROM users WHERE username='administrator'; -- AND password=''
The issue here is that the ' in the username closes out the username field then the -- starts a SQL comment causing the database server to ignore the rest of the string. The net result is the user can now log in as the administrator without having to know the password. SQL Inection can also be used to execute UPDATE, DELETE or DROP queries and really damage the database.
SQL Injection can be prevented by using parameterised queries, or applying your language/toolkit's escaping functions (such as mysql_real_escape_string() in PHP).
Once you understand SQL Injection you'll get the joke behind this cartoon.
SQL injection is when things that're supposed to be data are treated as SQL code unwillingly.
For instance, if you were to do
mysql_query("SELECT * FROM posts WHERE postid=$postid");
Normally it'd get you the post with a given id, but assume that $postid
is set to the string 10; DROP TABLE posts --
; all of a sudden, the actual query you're sending is
mysql_query("SELECT * FROM posts WHERE postid=10; DROP TABLE posts --");
This is quite a problem, as you'd be losing your entire posts table due to a malicious user - oh dear.
The easiest way to prevent this is to use prepared statements, for instance through PDO or MySQLi.
The equivalent example in PDO would then be
$statement = $db->prepare('SELECT * FROM posts WHERE postid = :postid');
$statement->bindValue(':postid', $postid);
$statement->execute();
Doing this ensures that the database system knows that $postid is to be treated as data and not code, and will thus be handled appropriately.
This question has been answered many times on StackOverflow, but it's an important topic for everyone to know about, so I'm not going to vote to close this question.
Here are links to some of my past answers on this topic:
I also gave a presentation at the MySQL Conference this month, and my slides are online:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With