Professional Documents
Culture Documents
To Counter SQL Injection Attacks
To Counter SQL Injection Attacks
To Counter SQL Injection Attacks
» Check coding nature of each and every page and take future prevention plan.
» Check for query string malfunction, border values and data types.
» Constrain and sanitize input data. Check for known good data by validating for type, length,
format, and range.
» Verify SQL Username & Password strength and users permission granted.
» Verify and cross check Stored Procedure input types and permission granted.
» Use type-safe SQL parameters for data access. Implement these constraints in stored
procedures or dynamically constructed SQL command strings.
» Create and verify SQL User account which would have restricted permissions in the
database. Only grant execute permissions to selected stored procedures in the database and
provide no direct table access.
» Avoid disclosing database error information. Verify and cross check with disclosing detailed
error messages to the user.
» As we've seen from many of examples, the majority of injection attacks require single
quotes to terminate an expression. So to avoid it Implement Functions and routines to
escape quotes.
» Rectify each query string with input and parameters and avoid culprit characters/ character
sequences by user defined functions. By removing these characters and character
sequences from user input before building a query, we could reduce the chances of an
injection attack even further.
» Verify genuine lengths of user input and limit it to a fixed variable. It's no good having a
text box on a form that can accept 50 characters if the field only accept 10. By keeping all
text boxes and form fields as short as possible.
SQL Injection
SQL injection is a technique used to take advantage of non-validated input vulnerabilities to pass SQL
commands through a Web application for execution by a backend database. Attackers take advantage of the
fact that programmers often chain together SQL commands with user-provided parameters, and can therefore
embed SQL commands inside these parameters. The result is that the attacker can execute arbitrary SQL
queries and/or commands on the backend database server through the Web application.
Details
Databases are fundamental components of Web applications. Databases enable Web applications to store
data, preferences and content elements. Using SQL, Web applications interact with databases to dynamically
build customized data views for each user. A common example is a Web application that manages products.
In one of the Web application's dynamic pages (such as ASP), users are able to enter a product identifier and
view the product name and description. The request sent to the database to retrieve the product's name and
FROM Products
Typically, Web applications use string queries, where the string contains both the query itself and its
parameters. The string is built using server-side script languages such as ASP, JSP and CGI, and is then sent
to the database server as a single SQL statement. The following example demonstrates an ASP code that
FROM Products
The call Request.QueryString("ProductID") extracts the value of the Web form variable ProductID so that it
FROM Products
An attacker may abuse the fact that the ProductID parameter is passed to the database without sufficient
validation. The attacker can manipulate the parameter's value to build malicious SQL statements. For
example, setting the value "123 OR 1=1" to the ProductID variable results in the following URL:
http://www.mydomain.com/products/products.asp?productid=123 or 1=1
FROM Products
This condition would always be true and all ProductName and ProductDescription pairs are returned. The
attacker can manipulate the application even further by inserting malicious commands. For example, an
TABLE Products
In this example the semicolon is used to pass the database server multiple statements in a single execution.
The second statement is "DROP TABLE Products" which causes SQL Server to delete the entire Products
table.
An attacker may use SQL injection to retrieve data from other tables as well. This can be done using the SQL
UNION SELECT statement. The UNION SELECT statement allows the chaining of two separate SQL
SELECT queries that have nothing in common. For example, consider the following SQL query:
SELECT ProductName, ProductDescription
FROM Products
respectively. An attacker may use this type of SQL injection by requesting the following URL:
http://www.mydomain.com/products/products.asp?productid=123 UNION
The security model used by many Web applications assumes that an SQL query is a trusted command. This
enables attackers to exploit SQL queries to circumvent access controls, authentication and authorization
checks. In some instances, SQL queries may allow access to host operating system level commands. This
can be done using stored procedures. Stored procedures are SQL procedures usually bundled with the
database server. For example, the extended stored procedure xp_cmdshell executes operating system
commands in the context of a Microsoft SQL Server. Using the same example, the attacker can set the value
of ProductID to be "123;EXEC master..xp_cmdshell dir--", which returns the list of files in the current directory
HTTP stream. For example, looking for SQL commands such as UNION, SELECT or xp_. The problem with
this approach is the very high rate of false positives. Most SQL commands are legitimate words that could
normally appear in the incoming HTTP stream. This will eventually case the user to either disable or ignore
any SQL alert reported. In order to overcome this problem to some extent, the product must learn where it
should and shouldn't expect SQL signatures to appear. The ability to discern parameter values from the entire
HTTP request and the ability to handle various encoding scenarios are a must in this case.
Imperva SecureSphere does much more than that. It observes the SQL communication and builds a profile
consisting of all allowed SQL queries. Whenever an SQL injection attack occurs, SecureSphere can detect the
unauthorized query sent to the database. SecureSphere can also correlate anomalies on the SQL stream with
Another important capability that SecureSphere introduces is the ability to monitor a user's activity over time
and to correlate various anomalies generated by the same user. For example, the occurrence of a certain SQL
signature in a parameter value might not be enough to alert for SQL injection attack but the same signature in
correlation with error responses or abnormal parameter size of even other signatures may indicate that this is
In my last article I looked at the threat of cross-site scripting (XSS) attacks and methods to thwart them.
In this tip, I want to look at another injection-based attack that has been making the news for some time:
SQL injection. What it is, how to prevent it and the tools available to assist you.
In the U.S. quite recently, hackers used a SQL injection attack to break into the 7-Eleven Inc. and
Hannaford Brothers Co. networks and steal credit card data. Although the same hackers used network
sniffers to capture card data from Heartland Payment Systems, it was a SQL injection attack that led to
the initial compromise of their servers, allowing the attackers to plant their malware. SQL injection
attacks represent a serious threat to any website with a database backend and require nothing more
than port 80 to be open, often working even if a system's patches are up to date.
Although the risk from SQL injection attacks has been well
SQL injection attacks on the documented, you can see they are still providing hackers with
rise? plenty of opportunities to access data or take control of a
compromised machine. The methods behind these attacks are
Security experts point to online easy to learn, and hackers have automated them to expedite the
advertising campaigns that process of finding and exploiting vulnerable websites. This
distributed faulty code to means that unless you take protective measures, like employing
affiliates as the source of spikes application security best practices or using SQL injection
in SQL injection attacks. detection tools, the site is much more likely to be uncovered and
exploited.
Many webpages take input from users, such as search terms, feedback comments or username and
password, and use them to build a SQL query which is passed to the database. If these inputs are not
validated, there is nothing to stop an attacker inputting malicious code, for example, that could instead
instruct the database to delete a specific table of client records.
Getting the SQL syntax right is not necessarily so simple and may require a lot of trial and error, but by
adding additional conditions to the SQL statement and evaluating the Web application's output, an
attacker can eventually determine whether, and to what extent, an application is vulnerable to SQL
injection. If the code achieves an immediate result, it is an example of a first-order attack. If the
malicious input is stored in a database to be retrieved and used later, such as providing input to a
dynamic SQL statement on a different page, it is referred to as a second-order attack. Second-order
attacks can be very successful because once data is in a database it is often deemed to be clean and
so is not revalidated prior to use.
SQL injection needs to be tackled on many levels, but the key defence is the use of parameterized
stored procedures. This is where requests to the database are made using parameters and user-defined
subroutines instead of building SQL commands using values supplied directly by a user. Parameters are
not only type safe (ie they are in a correct format), but they greatly reduce the likely success of a SQL
injection attack. If access to the data is only ever permitted via stored procedures, then permission for
users to access data does not need to be explicitly given on any data tables.
Even if you are using parameterized stored procedures, your application still needs to validate and
sanitize all data inputs, whether it is supplied by your users, authenticated customers or read from a
cookie. This means checking that the data is of the correct type, length, format and within an expected
range. Any data that is not well-formed and correct should be rejected.
Many applications sanitize input by filtering out known unsafe characters such as "<" and "/". However,
this is not best practice because malicious users can usually find an alternative means, such as
character encoding, to bypass this type of validation. Instead, your code should check for known secure,
safe input. This validation needs to take place on a trusted server, not on the client. Only once this
validation has taken place should data be passed on to your scripts or database. These checks also
apply to data received from internal applications or entered or edited by internal users; you have to
assume all data is from an untrusted source.
Web applications should never run with administrative privilege at the server level or at the database
level, otherwise an attacker could potentially perform any task available to an administrator. Run the
application with the least privileges that are necessary for it to function, and the database with
permissions set to only the essential resources. That way, an attacker is confined by a limited set of
permissions, should he or she succeed in bypassing your defences.
Any sensitive data stored in your database should be encrypted, such as personal details or user login
passwords. This type of data can be stored as a salted hash. A salt is a random set of characters which
is added to data before calculating its hash. While it still may be possible to determine a password by
dictionary attack, a unique salt for each hash causes an attacker to recalculate the dictionary for each
user's password, severely disrupting the attack.
Another aspect of application design and development that is often poorly executed and allows potential
attackers to finesse their SQL injection code is error handling. Many applications display a detailed error
message containing information about the structure of the application, network or database; an attacker
can use this to stage further attacks.
Error messages are therefore useful to an attacker because they give additional information about the
database or system that might not otherwise be available. Hackers typically test for and find SQL
injection vulnerabilities by sending the application inappropriate input to try and generate an invalid SQL
query. If the server then returns an error message, the attacker can use information gained from these
error messages to refine his or her attack. As coding errors are always a possibility, you need to make
sure your applications have a safe mode which they can return to if something truly unexpected occurs.
By all means, log any errors for your own records, but make sure your developers use a structured
exception handler, like try {} catch {}, and that all debug error handlers have been removed
from the production code.
A good Web vulnerability scanner will spot common technical vulnerabilities, such as SQL injection
flaws, cross-site scripting vulnerabilities, parameter tampering, hidden field manipulation, backdoors,
debug options and buffer overflows. If you use any third-party applications that utilise a database back-
end, it's vital that that you follow any vendor updates regarding vulnerabilities and patches to ensure the
new code isn't introducing vulnerabilities into your own system.
Even if your database administrators and application developers are following best practice, I would still
recommend the deployment of an application-layer firewall or Web application firewall (WAF). WAFs
can provide protection beyond that of traditional network firewalls and intrusion detection/prevention
systems. Many, like those produced by Imperva Inc. and Barracuda Networks Inc., can help prevent
attacks such as SQL injection, cross-site scripting and others that target flaws in application logic or
technical vulnerabilities in software.
Best-of-breed WAFs can recognise evasion techniques exploited by attackers using SQL injection, such
as obfuscating the attack by encoding portions of the injected command. Your chosen application-layer
firewall should also allow you to create filters to intercept, analyze or modify traffic specific to your
network.
Filters make it easier to adapt the firewall to protect assets or monitor traffic specific to your network.
Even better if it has the capability to "learn" what is and what isn't normal traffic for your specific network
and adapt its behavior accordingly. When irregularities are detected, the WAF can shut down potential
attacks while they're happening. Also as SQL injection often takes place via the URL query string, you
should regularly review your Web server's logs to look for anomalous queries that may be injection
attempts.
• abuse@
• admin@
• administrator@
• contact@
• info@
• postmaster@
• support@
• webmaster@
And you can, of course, proactively determine if you have a "badware" problem by using Google's free
Webmaster Tools.
SQL injection attacks have been shown to be lethal. They can be used to collect or destroy data held in
a database as well as be used as a launchpad to delve deeper into an organisation's network and
systems. By implementing some basic defences, you make your database a lot harder to crack.
With that being said, simple filtration of certain characters, keywords, and other attempts
to deter SQL injection are many times quite laughable to a security professional such as
myself who knows many ways to circumvent such countermeasures. Aside from some of the
feeble attempts at prevention I've seen, the end goal is to properly secure your resources
regardless of past code written. With the lack of Classic ASP examples to properly prevent
SQL injection, I am providing an example simple login page below on how to correctly and
incorrectly perform database queries using Classic ASP and VBScript. There are other
methods than the one shown below that work, but this seems to be the simplest. Enjoy!
<%@ Language = "VBScript" %>
<%
Option Explicit
Dim cnnLogin, rstLogin, strUsername, strPassword, strSQL
Const adCmdText = 1 'Evaluate as a textual
definition
Const adCmdStoredProc = 4 'Evaluate as a stored procedure
%>
<html>
<head><title>Login Page</title>
</head>
<body bgcolor="gray">