0

There's a lot of warnings about SQL injections here on SO, but no one I've found doesn't really answer, how does it happen? In this question, I'm assuming it's MySQL and PHP.

The basic mysql_ doesn't accept a second query inside a query, right?

So, basically, this

$unsafe = "');DROP TABLE table;--";    
mysqli_query($con,"INSERT INTO table (Column) VALUES ('$unsafe'");

doesn't actually do anything harmful? Correct me on this.

I've no experience working with mysqli_, so I'll skip to PDO, and "Prepared statements".

When I started working with PDO, I had a lack of information on it, and basically used it like this, thinking it's safe.

$stm = $pdo->prepare("INSERT INTO table (Column) VALUES ('$unsafe');
$stm->execute();

However, same thing with PDO as with mysql_. It doesn't support multiple queries out of the box, right? Again, correct me on this.

Then, this is consired safe, if I'm not wrong?

$stm = $pdo->prepare("INSERT INTO table (Column) VALUES (?);
$stm->execute(array($unsafe);

How does a malicious user with no access to the database inject malicious data, if multiple queries aren't even supported?

Or are they?

  • 1
    This is a question for [programmers.se] – Kermit Oct 29 '13 at 18:36
  • @FreshPrinceOfSO Feel free to flag it for migration. –  Oct 29 '13 at 18:38
  • possible duplicate of [How can I prevent SQL injection in PHP?](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) – Lawrence Cherone Oct 29 '13 at 18:38
  • Your example doesn't make valid SQL – PeeHaa Oct 29 '13 at 18:39
  • It's not just multiple queries, which are indeed disabled per default as you already researched. In case of your INSERT requests, a crafted string concatenation expression and SELECT subquery in `$unsafe` might be all an attacker needs to unveil database contents. – mario Oct 29 '13 at 18:41
  • @LawrenceCherone it doesn't really answer on HOW. –  Oct 29 '13 at 18:41
  • @PeeHaa What part of it? `$unsafe`? I'm not an expert in sql injections, I'd just want to learn on why and how they happen. –  Oct 29 '13 at 18:44
  • echo your concatenated query and try to run it – PeeHaa Oct 29 '13 at 18:46
  • See http://stackoverflow.com/a/7414582/187606 for an answer – Pekka Oct 29 '13 at 18:46
  • Take a look at: http://stackoverflow.com/questions/11939226/sql-injections-and-general-website-security – Ilia Ross Oct 29 '13 at 18:50
  • @mario Yes, revealing the database contents is quite easy, but how about adding another query? –  Oct 29 '13 at 18:56
  • @Christian, I would say that your code is safe if you prepare your SQL statement and execute it like `$stm->execute(array($unsafe);`. There would be no reason in having prepared statements otherwise. I would just add, that you must always escape everything, that is going to the database, even the content that is already in database. There are so called “Reversed” SQL Injections. I don't see how your prepared statement could be compromised!? – Ilia Ross Oct 29 '13 at 19:42
  • Yes, it's safe, I know that. But, as I did, and like many others, prepared statements can be used wrong, like this: `$stm = $pdo->prepare("INSERT INTO table (Column) VALUES ('$unsafe');` –  Oct 29 '13 at 19:46
  • Yes, this is for sure the wrong usage and helps absolutely not against SQL injections. I described it in my answer. – Ilia Ross Oct 30 '13 at 09:50

2 Answers2

1

How does a malicious user with no access to the database inject malicious data, if multiple queries aren't even supported?

"SQL injection" is not equal to "second query".

Or are they?

Surely they are.

Second query is just an example. While it can be any valid SQL statement. SQl injection is an exploit of improperly formatted query. If a developer don't format SQL properly, there is a possibility to break from limits of literal and add code to the SQL body.

Is an SQL injection actually possible by adding a second query?

Yes, depends on the API you are using.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
  • Yes, I'm aware of that. While http://stackoverflow.com/questions/332365/how-does-the-sql-injection-from-the-bobby-tables-xkcd-comic-work/7414582#7414582 explains it pretty carefully, it's still only **one** query, perfectly valid SQL. But what if user wants to add another query after it, like in my example. –  Oct 29 '13 at 18:51
  • I've edited the title to actually match the question. So by **any means** necessary, is it possible to actually add another query after the first one? –  Oct 29 '13 at 18:54
  • Yes, but it doesn't actually matter. You are asking wrong questions. – Your Common Sense Oct 29 '13 at 18:55
  • Subquestion then: Does PDO, by default then support it? Yes, in this case: http://stackoverflow.com/questions/6346674/pdo-support-for-multiple-queries-pdo-mysql-pdo-mysqlnd but without `try` & `catch`? –  Oct 29 '13 at 18:58
  • What try & catch has to do with this question? Do you quite understand, what you are asking about? – Your Common Sense Oct 29 '13 at 19:01
  • Yes, I know what I'm asking about, but pretty sure I'm expressing myself terribly here. If I understood correctly, `try { $db->exec($sql); }` was used to execute multiple queries inside one string? –  Oct 29 '13 at 19:08
  • He is just consider these to matters the same. – Your Common Sense Oct 29 '13 at 19:10
  • @YourCommonSense They're not the same, but it seems like the easiest way to do this. –  Oct 29 '13 at 19:13
0

Two queries with mysql + php is a fallacy

Did you really name your son "Robert'); Drop TABLE Students;--"

Source: http://xkcd.com/327/

This will not work with mysql and php without deliberate steps to make it possible, since the normal query function will only execute the first query.

That doesn't mean it's not possible - only that it should be very obvious when it is.

SQL injection is very real

But the above means almost nothing in terms of sql injection. There is a huge, huge amount of information out there about sql injection including a large number of questions here on stack overflow. Taking the example in the question, this is an equivalent attack which would work:

$id = "123 OR 1 = 1 --";
mysqli_query($con,"DELETE FROM table WHERE id = $id LIMIT 1");

i.e. finding an interface to delete my own, e.g., comment, if the id is not escaped it would be trivial to delete all comments. But this example is just the very tip of an iceberg.

Executing arbitrary sql statements are exploitable

This code in the question:

$stm = $pdo->prepare("INSERT INTO table (Column) VALUES ('$unsafe')");
$stm->execute();

Has none of the benefits of using PDO - i.e. any exploit (of the truly massive number) that would work with the mysql/mysqli driver (used naively) will work with pdo used in this way.

Parametrized queries protect against sql injection

Using PDO with prepared statements with parameters escapes values appropriately preventing sql injection attacks, so yes this is safe from injection:

$stm = $pdo->prepare("INSERT INTO table (Column) VALUES (?)");
$stm->execute(array($unsafe));

How does a malicious user with no access to the database inject malicious data

Simply by finding a way to execute sql that either does what they want to do, or gives them the information to do it a different way.

For example:

function login() {
    $username = "irrelevant' OR is_admin = 1 --";
    $password = hash('irrelevant');
    $query = "SELECT id from users where username = '$username' AND password = '$password'";
    ...
}

How did malicious user get access to the admin functionality on a system with no concern for injection? Very easily.

For general information about injection see the previous references.

Community
  • 1
  • 1
AD7six
  • 63,116
  • 12
  • 91
  • 123