How do I demonstrate a Second Order SQL Injection?

被刻印的时光 ゝ 提交于 2019-11-29 07:58:48

Using a first name of:

' OR 1 OR '

This will produce a where clause in the second SQL of

WHERE FirstName = '' OR 1 OR ''

Therefore the result will be the first record in the table.

By adding a LIMIT clause, you can extract all rows from the table with:

' OR 1 ORDER BY UserID ASC LIMIT 0, 1 --

Obviously it will only extract 1 row at a time, so you would need to repeat that and increment the 0 in the LIMIT. This example uses a comment -- to terminate the remaining SQL which would otherwise cause the query to fail because it would add a single quote after your LIMIT.

The above is a simple example, a more complex attack would be to use a UNION SELECT which would give you access to the entire DB through the use of information_schema.

Also you are using addslashes() in one of your queries. That is not as secure as mysql_real_escape_string() and in turn: escaping quotes with either is not as secure as using prepared statements or parameterised queries for example in PDO or MySQLi.

What is there to demonstrate?

Second order SQL injection is nothing more than SQL injection, but the unsafe code isn't the first line.

So, to demonstrate:

1) Create a SQL injection string that would do something unwanted when executed without escaping.

2) Store that string safely in your DB (with escaping).

3) Let some other piece of your code FETCH that string, and use it elsewhere without escaping.

EDIT: Added some examplecode:

A table:

CREATE TABLE tblUsers (
  userId serial PRIMARY KEY,
  firstName TEXT
)

Suppose you have some SAFE code like this, receiving firstname from a form:

$firstname = someEscapeFunction($_POST["firstname"]);

$SQL = "INSERT INTO tblUsers (firstname) VALUES ('{$firstname }');";
someConnection->execute($SQL);

So far, so good, assuming that someEscapeFunction() does a fine job. It isn't possible to inject SQL.

If I would send as a value for firstname the following line, you wouldn't mind:

bla'); DELETE FROM tblUsers; //

Now, suppose somebody on the same system wants to transport firstName from tblUsers to tblWhatever, and does that like this:

$userid = 42;
$SQL = "SELECT firstname FROM tblUsers WHERE (userId={$userid})";
$RS = con->fetchAll($SQL);
$firstName = $RS[0]["firstName"];

And then inserts it into tblWhatever without escaping:

$SQL = "INSERT INTO tblWhatever (firstName) VALUES ('{$firstName}');";

Now, if firstname contains some deletecommand it will still be executed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!