52
Chapter 2 • Testing for SQL Injection
This is a very common scenario. It happens when the application does not handle errors
and no custom error page has been configured on the server. As I showed before, this behavior
is determined by the web.config file settings.
If you are testing a Web site and discover that the application is always responding with
a default or custom error page, you will need to make sure the error is due to SQL injection.
You can test this by inserting SQL code into the parameter without triggering an
application error.
In the preceding example, you can assume that the SQL query is going to be something
such as this:
SELECT *
FROM products
WHERE category='[attacker's control]'
Figure 2.6
Default ASP.NET Error Page
Testing for SQL Injection • Chapter 2
53
Injecting
attacker’
is clearly going to generate an error, as the SQL statement is incorrect
due to the extra single quote at the end:
SELECT *
FROM products
WHERE category='attacker''
However, you can try to inject something that doesn’t generate an error. This is usually
an educated trial-and-error process. In our example, we need to keep in mind that we are
trying to inject data into a string enclosed with single quotes.
What about injecting something such as
bikes’ or ‘1’=’1
? The resultant SQL statement
would be:
SELECT *
FROM products
WHERE category='bikes' OR '1'='1' /* always true -> returns all rows */
In this example, we injected SQL code that created a meaningful correct query. If the
application is vulnerable to SQL injection, the preceding query should return every row in
the
products
table. This technique is very useful, as it introduces an
always true
condition.
‘ or ‘1’=’1
is inserted inline with the current SQL statement and does not affect the
other parts of the request. The complexity of the query doesn’t particularly matter, as we can
easily create a correct statement.
One of the disadvantages of injecting an
always true
condition is that the result of the query
will contain every single record in the table. If there are several million records, the query
can take a long time to execute and can consume many resources of the database and Web
servers. One solution to this is to inject something that will have no effect on the final result;
for example,
bikes’ or ‘1’=’2.
The final SQL query would be:
SELECT *
FROM products
WHERE category='bikes' OR '1'='2'
Because 1 is not equal to 2, and therefore the condition is false, the preceding statement
is equivalent to:
SELECT *
FROM products
WHERE category='bikes'
Another test to perform in this kind of situation is the injection of an
always false
statement. For that we will send a value that generates no results; for example,
bikes’
AND ‘1’=’2
:
SELECT *
FROM products
WHERE category='bikes' AND '1'='2' /* always false -> returns no rows */
Do'stlaringiz bilan baham: |