SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a...

21
6 SQL INJECTION ATTACKS INFORMATION IN THIS CHAPTER What Is an SQL Injection Attack? Why Are SQL Injection Attacks So Successful? How to Protect Yourself from an SQL Injection Attack Cleaning Up the Database After an SQL Injection Attack What Is an SQL Injection Attack? An SQL Injection Attack is probably the easiest attack to prevent, while being one of the least protected against forms of attack. The core of the attack is that an SQL command is appended to the back end of a form field in the web or appli- cation front end (usually through a website), with the intent of breaking the original SQL Script and then running the SQL script that was injected into the form field. This SQL injection most often happens when you have dynamically generated SQL within your front-end application. These attacks are most common with legacy Active Server Pages (ASP) and Hypertext Preprocessor (PHP) applications, but they are still a problem with ASP.NET web-based applications. The core reason behind an SQL Injection attack comes down to poor coding practices both within the front-end application and within the database stored procedures. Many developers have learned better development practices since ASP.NET was released, but SQL Injection is still a big problem between the number of legacy applications out there and newer applications built by devel- opers who didn’t take SQL Injection seriously while building the application. As an example, assume that the front-end web application creates a dynamic SQL Script that ends up executing an SQL Script similar to that shown in Example 6.1. SELECT * FROM Orders WHERE OrderId¼25 Example 6.1: A simple dynamic SQL statement as expected from the application. Securing SQL Server 149

Transcript of SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a...

Page 1: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

6SQL INJECTION ATTACKS

INFORMATION IN THIS CHAPTER� What Is an SQL Injection Attack?

� Why Are SQL Injection Attacks So Successful?

� How to Protect Yourself from an SQL Injection Attack

� Cleaning Up the Database After an SQL Injection Attack

What Is an SQL Injection Attack?An SQL Injection Attack is probably the easiest attack to

prevent, while being one of the least protected against forms ofattack. The core of the attack is that an SQL command isappended to the back end of a form field in the web or appli-cation front end (usually through a website), with the intent ofbreaking the original SQL Script and then running the SQLscript that was injected into the form field. This SQL injectionmost often happens when you have dynamically generated SQLwithin your front-end application. These attacks are mostcommon with legacy Active Server Pages (ASP) and HypertextPreprocessor (PHP) applications, but they are still a problemwith ASP.NET web-based applications. The core reason behindan SQL Injection attack comes down to poor coding practicesboth within the front-end application and within the databasestored procedures. Many developers have learned betterdevelopment practices since ASP.NET was released, but SQLInjection is still a big problem between the number of legacyapplications out there and newer applications built by devel-opers who didn’t take SQL Injection seriously while building theapplication.

As an example, assume that the front-end web applicationcreates a dynamic SQL Script that ends up executing an SQLScript similar to that shown in Example 6.1.

SELECT * FROM Orders WHERE OrderId¼25

Example 6.1: A simple dynamic SQL statement as expected from the application.Securing SQL Server

149

Page 2: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

This SQL Script is created when the customer goes to the salesorder history portion of the company’s website. The value passedin as the OrderId is taken from the query string in the URL, so thequery shown above is created when the customer goes to the URLhttp://www.yourcompany.com/orders/orderhistory.aspx?Id¼25.Within the .NET code, a simple string concatenation is done toput together the SQL Query. So any value that is put at the end ofthe query string is passed to the database at the end of the selectstatement. If the attacker were to change the query string tosomething like “/orderhistory.aspx?id¼25; delete from Orders,”then the query sent to the SQL Server will be a little moredangerous to run as shown in Example 6.2.

SELECT * FROM Orders WHERE ORderId¼25; delete from Orders;

Example 6.2: A dynamic SQL String that has had a delete statement concate-nated to the end of it.

The way the query in Example 6.2 works is that the SQLdatabase is told via the semicolon “;” that the statement hasended and that there is another statement that should be run. TheSQL Server then processes the next statement as instructed.

While the initial query is run as normal now, and withoutany error being generated but when you look at the Orderstable, you won’t see any records in the Orders table because thesecond query in that batch will have executed againstthe database as well. Even if the attacker omits the value thatthe query is expecting, they can pass in “; delete from Orders;”and while the first query attempting to return the data from theOrders table will fail, the batch will continue moving on to thenext statement, which will delete all the records in the Orderstable.

Many people will inspect the text of the parameters looking forvarious key words in order to prevent these SQL Injection attacks.However, this only provides the most rudimentary protection asthere are many, many ways to force these attacks to work. Someof these techniques include passing in binary data, having theSQL Server convert the binary data back to a text string, and thenexecuting the string. This can be proven by running the T/SQLstatement shown in Example 6.3.

DECLARE @v varchar(255)

SELECT @v ¼ cast(0x73705F68656C706462 as varchar(255))

EXEC (@v)

Example 6.3: Code showing how a binary value can be used to hide a T/SQLstatement.

150 Chapter 6 SQL INJECTION ATTACKS

Page 3: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

When data is being accepted from a user, either a customeror an employee, one good way to ensure that the value won’t beused for an SQL Injection attack is to validate that the databeing returned is of the expected data type. If a number isexpected, the front-end application should ensure that there isin fact a number within the value. If a text string is expected,then ensure that the text string is of the correct length, and itdoes not contain any binary data within it. The front-endapplication should be able to validate all data being passed infrom the user, either by informing the user of the problem andallowing the user to correct the issue, or by crashing gracefullyin such a way that an error is returned and no commands aresent to the database or the file system. Just because usersshould be sending up valid data doesn’t mean that they aregoing to. If users could be trusted, most of this book wouldn’tbe needed.

The same technique shown in Example 6.3 can be used to sendupdate statements into the database, causing values to be places

NoteThe Database Isn’t the Only Weak Spot

If a file name is going to be generated based on the user’s input, a few special values should be watched for. Thesevalues are Windows file system key words that could be used to give attackers access to something they shouldn’t have,or could simply cause havoc on the front-end server.� AUX� CLOCK$� COM1-COM8� CON� CONFIG$� LPT1-LPT8� NUL� PRN

By allowing an attacker to create a file path using these special names, attackers could send data to a serial port byusing COM1 (or whatever com port number they specify) or to a printer port using LPT1 (or whatever printer port theyspecify). Bogus data could be sent to the system clock by using the CLOCK$ value, or they could instruct the fileto be written to NUL, causing the file to simply disappear.

Chapter 6 SQL INJECTION ATTACKS 151

Page 4: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

within the database that will cause undesirable side effects on thewebsites powered by the databases. This includes returningjavascript to the client computers causing popups that show adsfor other projects, using HTML iframes to cause malicious soft-ware to be downloaded, using HTML tags to redirect the browsersession to another website, and so on.

SQL Injection attacks aren’t successful against only in-houseapplications. A number of third-party applications available forpurchase are susceptible to these SQL Injection attacks. Whenpurchasing third-party applications, it is often assumed that theproduct is a secure application that isn’t susceptible to theattack. Unfortunately, that isn’t the case, and any time a third-party application is brought into a company, it should bereviewed, with a full code review if possible, to ensure that theapplication is safe to deploy. When a company deploys a third-party application that is susceptible to attack and that appli-cation is successfully attacked, it is the company that deployedthe application that will have to deal with the backlash forhaving an insecure application and their customer datacompromised, not the company that produced and sold theinsecure application.

Many people think that SQL Injection attacks are a problemunique to Microsoft SQL Server, and those people would bewrong. SQL Injection attacks can occur against Oracle, MySQL,DB2, Access, and so on. Any database that allows multiplestatements to be run in the same connection is susceptible to anSQL Injection attack. Now some of the other database platformshave the ability to turn off this function, some by default andsome via an optional setting. There are a number of tickets openin the Microsoft bug-tracking website http://connect.microsoft.com that are requesting that this ability be removed froma future version of the Microsoft SQL Server product. While doingso would make the Microsoft SQL Server product more secure, itwould break a large number of applications, many of which areprobably the ones that are susceptible to SQL Injection attacks.

Another technique that is easier to use against Microsoft SQLServer 7 and 2000 is to use the sp_makewebtask system storedprocedure in the master database. If the attacker can figure outthe name of the webserver, which can usually be done prettyeasily by looking at the sysprocesses table, or the path to thewebsite, then the sp_makewebtask procedure can be used toexport lists of objects to HTML files on the web server to make iteasier for the attacker to see what objects are in the database.Then they can simply browse to the website and see every table inthe database.

152 Chapter 6 SQL INJECTION ATTACKS

Page 5: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

exec master.dbo.sp_makewebtask '\\web1\wwwroot\tables.html","select ) from information_schema.tables"

Code that an attacker could execute to export all table objects to an HTML file.

If xp_cmdshell is enabled on the server, then an attacker coulduse xp_cmdshell to do the same basic thing just by using BulkCopy Protocol (BCP) instead of sp_makewebtask. The advantageto sp_makewebtask is that xp_cmdshell doesn’t need to beenabled, while the downside to sp_makewebtask is that it doesn’texist on Microsoft SQL Server 2005 and up. The downside toxp_cmdshell is that, unless the application uses a login that isa member of the sysadmin fixed server role, the xp_cmdshellprocedure will only have the rights that are granted by the proxyaccount. An attacker can use the xp_cmdshell procedure to sendin the correct commands to give the account that is the proxyaccount more permissions, or even change the account to onethat has the correct permissions. At this point BCP can be used tooutput whatever data is wanted. The attacker could start withdatabase schema information, and then begin exporting yourcustomer information, or they could use this information tochange or delete the data from the database.

The catch to either of these techniques is that the NT FileSystem (NTFS) permissions need to allow either the SQL Serveraccount or the account that the xp_cmdshell proxy account usesto have network share and NTFS permissions to the web server.On smaller applications where the web server and the databaseserver are running on the same machine, this is much, mucheasier as the SQL Server is probably running as the local systemaccount that gives it rights to everything.

NoteThere Are Lots of Protection Layers to Make Something Secure

Hopefully, by now you are starting to see how the various layers of the Microsoft SQL Server need to be securedto make for a truly secure SQL Server. In this case we look specifically at NTFS permissions combined with thexp_cmdshell proxy account, combined with the Windows account that the SQL Server is running under, combined withthe application account that logs into SQL having the minimum level of rights, and combined with parameterizing thevalues from the web application all to create a more secure environment.

To fully protect from an SQL injection attack, the application account should only have the minimum rights neededto function; it should have no rights to xp_cmdshell, which should be disabled (or removed from the server). TheSQL Server service should be running under a domain or local computer account that only has the rights needed to run asa service and access the SQL Server folders. That Windows account should have no rights to the actual files that arethe website files, and it shouldn’t be an administrator on the server that is running the SQL Server service

Chapter 6 SQL INJECTION ATTACKS 153

Page 6: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

Why Are SQL Injection AttacksSo Successful?

SQL Injection attacks are so successful for a few reasons, themost common of which is that many newer developers simplydon’t know about the problem. With project timelines being soshort, these junior developers don’t have the time to research thesecurity implications of using dynamic SQL. These applicationsthen get left in production for months or years, with little to nomaintenance. These developers can then move through theircareer without anyone giving them the guidance needed toprevent these problems.

Now developers aren’t solely to blame for SQL Injection attackproblems. The IT Management should have policies in place inorder to ensure that newer developers that come in don’t have theability to write dynamic inline SQL against the database engine.These policies should include rules like the following:1. All database interaction must be abstracted through stored

procedures.2. No stored procedure should have dynamic SQL unless there is

no other option.

NotedCont'dor the web server. The resulting effective permissions that an SQL Server has are to access the database files and donothing else. Any other functions that the SQL Server instance is expected to perform either via an SQL Agent job or a CLRprocedure should be controlled through some sort of account impersonation.

At the application level the actual SQL Server error messages should be masked so that they aren’t returned tothe client. If you have done these things, then even if attackers were able to successfully complete an SQL Injectionattack against the SQL Server they wouldn’t be able to do much to the server as they wouldn’t have any way to getinformation back from the SQL Server (as the error messages are masked) and they wouldn’t be able to get to theshell and get software downloaded and installed from the outside. Once these things fail a few times, attackers willprobably just move on to an easier target.

The amount of time that an attacker will spend trying to successfully use an SQL Injection attack against a web-basedapplication will for the most part depend on the amount of value the target has. A smaller company such asa wholesale food distributor probably won’t be attacked very often, and the attacker will probably leave after a shortperiod of time. However, a bank or other financial company will provide a much more enticing target for theattacker, and the attack will probably last much longer, with many more techniques being tried, as well as manycombinations of techniques until they successfully break into the database application.

154 Chapter 6 SQL INJECTION ATTACKS

Page 7: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

3. Applications should have no access to table or view objectsunless requiredbydynamic SQL,which is allowedunder rule #2.

4. All database calls should be parameterized instead of beinginline dynamic SQL.

5. No user input should be trusted and thought of as safe; all userinteractions are suspect.

With the introduction of Object Relational Mappings (ORM)such as Link to SQL and nHybernate, the SQL Injection problemsare greatly lessened as properly done ORM code will automaticallyparameterize the SQL queries. However, if the ORM calls storedprocedures, and those stored procedures have dynamic SQLwithinthem, the application is still susceptible to SQL Injection attacks.

How to Protect Yourself from an SQLInjection Attack

Once the command gets to the database to be run by thedatabase engine, it is too late to protect yourself from the SQL

WarningSQL Injection Happens at All Levels

Unfortunately, not just small companies can have problems with SQL Injection attacks. In 2009, for example, ZD Netreported that some of the international websites selling Kaspersky antivirus, specifically Kaspersky Iran, Taiwan,and South Korea, were all susceptible to SQL Injection attacks. In the same article (http://bit.ly/AntiVirusSQLInject) ZDNet also reported that websites of F-Secure, Symantec, BitDeffender, and Kaspersky USA all had problems withSQL Injection attacks on their websites.

These are some of the major security companies of the day, and they are showing a total lack of security by lettingtheir websites fall prey to the simple injection attack. Considering just how simple it is to protect a website from anSQL injection attack, the fact that some of the biggest security companies in the industry were able to have SQLInjection problems on their production customer facing websites is just ridiculous.

Because of how intertwined various websites are with each other, real-estate listing providers and the realtorswhich get their data from the listing providers, a lot of trust must exist between these companies and the people whouse one companies site without knowing that they are using another companies data. This places the company that isshowing the real-estate listings to their users in a position of trusting the advertising company to have a safeapplication. However, this trust can backfire as on a few occasions various partner companies have suffered from SQLInjection attacks, in some cases pushing out malicious software to the users of dozens, hundreds, or thousands ofdifferent websites that display the data.

Chapter 6 SQL INJECTION ATTACKS 155

Page 8: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

Injection attack. The only way to truly protect your databaseapplication from an Injection attack is to do so within theapplication layer. Any other protection simply won’t be anywherenearly as effective. Some people think that doing a characterreplacement within the T/SQL code will effectively protect you,and it might to some extent. But depending on how the T/SQL isset up and how the dynamic SQL string is built, it probably won’t,at least not for long.

NET Protection Against SQL InjectionThe only surefire way to protect yourself is to parameterize

every query that you send to the database. This includes yourstored procedure calls, as well as your inline dynamic SQL calls.In addition, you never want to pass string values that the front-end application has allowed the user to enter directly intodynamic SQL within your stored procedure calls. If you havecause to use dynamic SQL within your stored procedures (andyes, there are perfectly legitimate reasons for using dynamicSQL), then the dynamic SQL needs to be parameterized justlike the code that is calling the stored procedure or inlinedynamic SQL Script. This is done by declaring parameters withinthe T/SQL statement, and adding those parameters to theSQLCommand object that has the SQL Command that you will berunning, as shown in Example 6.4 and Example 6.5.

Private Sub MySub()

Dim Connection As SqlConnection

Dim Results As DataSet

Dim SQLda As SqlDataAdapter

Dim SQLcmd As SqlCommand

SQLcmd ¼ New SqlCommand

SQLcmd.CommandText ¼ "sp_help_job"

SQLcmd.CommandType ¼ CommandType.StoredProcedure

SQLcmd.Parameters.Add("job_name", SqlDbType.VarChar, 50)

SQLcmd.Parameters.Item("job_name").Value ¼ "test"

Connection ¼ New SqlConnection("Data Source¼localhost;Initial Catalog¼msdb;Integrated

Security¼SSPI;")

Using Connection

Connection.Open()

SQLcmd.Connection ¼ Connection

SQLda ¼ New SqlDataAdapter(SQLcmd)

Results ¼ New DataSet()

SQLda.Fill(Results)

End Using

'Do something with the results from the Results variable here.

156 Chapter 6 SQL INJECTION ATTACKS

Page 9: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

SQLcmd.Dispose()

SQLda.Dispose()

Results.Dispose()

Connection.Close()

Connection.Dispose()

End Sub

Example 6.4: VB.NET code showing how to use parameters to safely calla stored procedure.

private void MySub()

{

SqlConnection Connection ¼ new SqlConnection("Data

Source¼localhost;Initial Catalog¼msdb;Integrated

Security¼SSPI;");

DataSet Results ¼ new DataSet();

SqlCommand SQLcmd ¼ new SqlCommand ();

SQLcmd.CommandText ¼ "sp_help_job";

SQLcmd.CommandType ¼ CommandType.StoredProcedure ;

SqlParameter parm1 ¼ new SqlParameter();

parm1.ParameterName ¼ "job_name";

parm1.DbType ¼ DbType.String;

parm1.Precision ¼ 255;

parm1.Value ¼ "test";

SQLcmd.Parameters.Add(parm1);

Connection.Open();

SQLcmd.Connection ¼ Connection;

SqlDataAdapter SQLda ¼ new SqlDataAdapter(SQLcmd);

SQLda.Fill(Results);

//Do something with the results from the Results variable

here.

SQLcmd.Dispose();

SQLda.Dispose();

Results.Dispose();

Connection.Close();

Connection.Dispose();

}

Example 6.5: C# code showing how to use parameters to safely call a storedprocedure.

As you can see in the above, .NET code using a parameter topass in the value is easy to do, adding just a couple of extra lines ofcode. The same can be done with an inline dynamic SQL string, asshown in Example 6.6 and Example 6.7.

Private Sub MySub()

Dim Connection As SqlConnection

Dim Results As DataSet

Dim SQLda As SqlDataAdapter

Chapter 6 SQL INJECTION ATTACKS 157

Page 10: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

Dim SQLcmd As SqlCommand

SQLcmd ¼ New SqlCommand

SQLcmd.CommandText ¼ "SELECT ) FROM dbo.sysjobs WHERE name¼@job_name"

SQLcmd.Parameters.Add("job_name", SqlDbType.VarChar, 50)

SQLcmd.Parameters.Item("job_name").Value ¼ "test"

SQLcmd.CommandType ¼ CommandType.Text;

Connection ¼ New SqlConnection("Data

Source¼localhost;Initial

Catalog¼msdb;Integrated Security¼SSPI;")

Using Connection

Connection.Open()

SQLcmd.Connection ¼ Connection

SQLda ¼ New SqlDataAdapter(SQLcmd)

Results ¼ New DataSet()

SQLda.Fill(Results)

End Using

'Do something with the results from the Results variable here.

SQLcmd.Dispose()

SQLda.Dispose()

Results.Dispose()

Connection.Close()

Connection.Dispose()

End Sub

Example 6.6: VB.NET code showing how to use parameters to safely call aninline dynamic SQL String.

private void MySub()

{

SqlConnection Connection ¼ new SqlConnection("Data-

Source¼localhost;Initial Catalog¼msdb;Integrated

Security¼SSPI;");

DataSet Results ¼ new DataSet();

SqlCommand SQLcmd ¼ new SqlCommand ();

SQLcmd.CommandText ¼ "SELECT ) FROM dbo.sysjobs WHERE

name ¼ @job_name";

SQLcmd.CommandType ¼ CommandType.Text;

SqlParameter parm1 ¼ new SqlParameter();

parm1.ParameterName ¼ "job_name";

parm1.DbType ¼ DbType.String;

parm1.Precision ¼ 255;

parm1.Value ¼ "test";

SQLcmd.Parameters.Add(parm1);

Connection.Open();

SQLcmd.Connection ¼ Connection;

SqlDataAdapter SQLda ¼ new SqlDataAdapter(SQLcmd);

SQLda.Fill(Results);

//Do something with the results from the Results variable

here.

158 Chapter 6 SQL INJECTION ATTACKS

Page 11: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

SQLcmd.Dispose();

SQLda.Dispose();

Results.Dispose();

Connection.Close();

Connection.Dispose();

}

Example 6.7: C# code showing how to use parameters to safely call an inlinedynamic SQL String.

Once each parameter that is being passed into the database hasbeen protected, the .NET code (or whatever language is beingused to call the database) becomes safe. Any value that is passedfrom the client side to the database will be passed into the data-base as a value to the parameter. In the example code shown at thebeginning of this chapter, the string value that has been passedinto the application would then force an error to be returned fromthe client Microsoft SQL Server database as the value would bepassed into a parameter with a numeric data type.

Using the sample query shown in the .NET sample code inExamples 6.6 and 6.7, if the user were to pass in similar attack codetowhat is shown in the SQL Server sample code in Example 6.2, thequery that would be executed against the database would look likethe one shown in Example 6.8. This resulting query is now safe torun as the result which is executed against the database enginecontains all the attack code as a part of the value.

SELECT * FROM dbo.sysjobs WHERE name ¼ 'test; delete from Orders';

Example 6.8: Sample T/SQL code showing the resulting T/SQL Code that wouldbe executed against the database if an attacker were to put in an attack codeagainst the prior sample .NET code.

NoteDon’t Trust Anything or Anyone!

The golden rule when dealing with SQL Injection is to not trust any input from the website or front-end application. Thisincludes hidden fields and values from dropdown menus. Nothing should be passed from the front end to the databasewithout being cleaned and properly formatted, as any value passed in from the front end could be compromised.

Hidden fields are probably the SQL Injection attacker’s best friend. Because they are hidden from the end user’s viewand are only used by system processes, they are sometimes assumed to be safe values. However, changing the valuesthat are passed in from a safe value to a dangerous value is a trivial matter for a script kitty, much less a skilled attacker.

When dealing with SQL Injection, the mantra to remember is never, ever, trust anything that is sent to theapplication tier from the end user, whether or not the end user knows that he submitted the value.

Chapter 6 SQL INJECTION ATTACKS 159

Page 12: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

In the sample code you can see that while the attack code hasbeen passed to the engine, it has been passed as part of the valueof the WHERE clause. However, because this is within the value ofthe parameter, it is safe because the parameter is not executable.If attackers were to pass in the same command with a singlequote in front of it, in an attempt to code the parameter, and thenexecute their own code, the single quote would be automaticallydoubled by the .NET layer when it passed to the SQL Serverdatabase again, leaving a safe parameter value as shown inExample 6.9.

SELECT * FROM dbo.sysjobs WHERE name¼ 'test''; delete from Orders';

Example 6.9: The resulting T/SQL code that would be executed against thedatabase when an attacker passes in an attack string with a single quote in anattempt to bypass the protection provided by the .NET application layer.

Protecting Dynamic SQL within StoredProcedures from SQL Injection Attack

When you have dynamic SQL within your stored procedures,you need to use a double protection technique to prevent theattack. The same procedure needs to be used to protect theapplication layer and prevent the attack from succeeding at thatlayer. However, if you use simple string concatenation withinyour stored procedure, then you will open your database back upto attack. Looking at a sample stored procedure and the resultingT/SQL that will be executed against the database by the storedprocedure; we can see that by using the simple string concate-nation, the database is still susceptible to the SQL Injectionattack, as shown in Example 6.10.

CREATE PROCEDURE sel_OrdersByCustomer

@LastName VARCHAR(50)

AS

DECLARE @cmd NVARCHAR(8000)

SET @cmd ¼ 'SELECT )

FROM Orders

JOIN Customers ON Orders.CustomerId ¼ Customers.CustomerId

WHERE Customers.LastName ¼ ''' þ @LastName þ ''''EXEC (@cmd)

GO

/)The command that will be executed when the attacker passed

in '; DELETE FROM Orders.)/

SELECT )

FROM Orders

160 Chapter 6 SQL INJECTION ATTACKS

Page 13: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

JOIN Customers ON Orders.CustomerId ¼ Customers.CustomerId

WHERE Customers.LastName ¼ 'Smith'; DELETE FROM Orders '

Example 6.10: T/SQL stored procedure that accepts a parameter from theapplication layer and concatenates the passed-in value to the static portion ofthe string, executing whatever attack code the attacker wishes against thedatabase engine.

Because of the value attack, the value being passed into the SQLServer Engine is passed in through the application layer, and theSQL Server engine does as it is instructed to do, which is to run thequery. However, if we parameterize the dynamic SQL withinthe stored procedure, then the execute SQL code will be renderedharmless just as it would be if the dynamic SQL was executedagainst the database by the application layer. This is done via thesp_executesql system stored procedure as shown in Example 6.11.

CREATE PROCEDURE sel_OrdersByCustomer

@LastName VARCHAR(50)

AS

DECLARE @cmd NVARCHAR(8000)

SET @cmd ¼ 'SELECT )

FROM Orders

JOIN Customers ON Orders.CustomerId ¼ Customers.CustomerId

WHERE Customers.LastName ¼ ''' þ @LastName þ ''''EXEC sp_executesql @cmd, '@LastName VARCHAR(50)',

@LastName¼@LastName

GO

/)The command that will be executed when the attacker passed in ';DELETE FROM Orders.)/

SELECT )

FROM Orders

JOIN Customers ON Orders.CustomerId ¼ Customers.CustomerId

WHERE Customers.LastName ¼ 'Smith''; DELETE FROM Orders '

Example 6.11: T/SQL stored procedure that accepts a parameter from theapplication layer and uses parameterization to safely execute the query passingwhatever attack code the users input safely against the database as a simplestring value.

Removing Extended Stored ProceduresIn addition to running all code from the application layer as

parameterized commands instead of dynamically generatedT/SQL, you should also remove the system procedures that canbe used to export data. The procedures in question that you’llwant to remove are xp_cmdshell, xp_startmail, xp_sendmail,

Chapter 6 SQL INJECTION ATTACKS 161

Page 14: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

sp_makewebtask, and sp_send_dbmail. You may also want toremove the procedures that configure Database Mail such assysmail_add_account_sp and sysmail_add_profileaccount_sp, sothat attackers can’t use these procedures to give themselves a wayto e-mail out information from the database. Of course, you’llwant to make sure that you aren’t using these procedures in anyreleased code and that you have Database Mail configured beforeremoving your ability to configure it.

Of course, removing system stored procedures poses a risk ofcausing system upgrades to fail, so you’ll want to keep copies ofthese objects handy so that you can put the objects back beforedatabase version upgrades.

Unfortunately, this isn’t a surefire way to prevent an attackerfrom using these procedures. Crafty attackers can actually putthese procedures back after they see that they have beenremoved. This is especially true of the extended stored proce-dures called DLLs (Dynamic Link Libraries), which must be left intheir normal locations because other extended stored proceduresthat you don’t want to remove are part of the sameDLLs. The onlysaving grace is that you have to be a highly privileged user withinthe database engine to put an extended stored procedure into theSQL Server engine. Thus, the only way that an attacker couldsuccessfully put the extended stored procedures back would be tolog into the database with a highly privileged account. If yourapplication logs into the database engine using a highly privilegedaccount, all bets are off as the attacker now has the rights neededto put the extended stored procedures back.

Not Using Best Practice Code Logic Can Hurt YouThe application login process is probably the most important

one that an attacker may want to take advantage of. Many timeswhen developers are building a login process, the front-enddeveloper will simply look for records in a record set, and if thereare none will assume that the user didn’t login correctly. If thereare records in the record set, the developer will assume that theuser logged in correctly and so will grab the first record and usethat record to find the user’s permissions. Attackers wishing toexploit this situation would be able to get past the login screen,probably being logged in with a high level of permissions. This isdone by adding a small text string in the username field such as“user’ OR 1¼1 e“. What this will do is change the code shown inExample 6.12 into the code shown in Example 6.13. Example 6.14shows the T/SQL code that would be executed against the data-base engine.

162 Chapter 6 SQL INJECTION ATTACKS

Page 15: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

SELECT ) FROM dbo.Users WHERE UserName ¼ 'user' AND Password ¼'password'

Example 6.12: The way a sample record set looks when validating a useraccount.

SELECT ) FROM dbo.Users WHERE UserName ¼ 'user' OR 1¼1 – AND

Password ¼ 'password'

Example 6.13: The way the code looks when the attack code has been inserted.

SELECT ) FROM dbo.Users WHERE UserName ¼ 'user' OR 1¼1

Example 6.14: The executable part of the code against the database engine fromthe prior sample code.

Because of the OR clause in the prior sample code, it doesn’tmatter if there is a record where the UserName column equalsuser because the 1 ¼ 1 section will tell the database to returnevery record in the database.

As you can see in the sample code above, the code that getsexecuted against the database engine would return the entireUser table. Assuming that the front-end application simply takesthe first record from the record set returned from the database,the attacker would then be logged into the application, probablywith an administrative-level account. Preventing this sort ofattack is easy; refer back to the beginning of this section of thischapter for the sample .NET code. Now that the user has beenlogged in, potentially with administrative rights, the user doesn’tneed to use any additional dynamic SQL to get access to yourcustomer data, as he or she will now have full access through yournormal administrative system.

What to Return to the End UserThe next important thing to configure within the front-end

application is what errors are returned to the end user. When thedatabase throws an error, you should be sure to mask the errorfrom the end user. The end user doesn’t have any need to knowthe name of either the primary key or the foreign key that hasbeen violated. You might want to return something that the enduser can give to customer service or the help desk so that theactual error message can be looked up.

What this has to do with SQL injection is important. If theattacker is able to send in code that breaks the query and returnsan error, the error may well contain the name of a table or otherdatabase object within the error message. For example, if theattacker sends in an attack string of “‘ Group by CustomerId –”to a query that looks like “SELECT ) FROM Customers WHERE

Chapter 6 SQL INJECTION ATTACKS 163

Page 16: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

UserName ¼ ‘UserName’ AND Password ¼ ‘Password’” creatingthe query “SELECT ) FROM Customers WHERE UserName ¼‘UserName‘ Group by CustomerId – AND Password ¼ ‘Pass-word’”. The default error message that SQL Server would returngives the attackers more information than they had before. It tellsthem the table name. The attacker can use this same technique tofigure out which columns are in the table. Over all, Being able tosee the actual SQL Server error message, even if the error doesn’tgive the attacker any database schema information it tells theattacker that the attack attempt was successful. By using thesp_MSforeachtable system stored procedure and the raiserrorfunction, the attackers could easily return the list of every table inthe database, giving them a wealth of information about thedatabase schema, which could then be used in future attacks.

There is more useful information that an attacker could getthanks to the error message being returned. For example, if theusers were to run a stored procedure in another database thatthey didn’t have access to, the error message would return theusername of the usedfor example, if the attacker sends in anattack string “’; exec model.dbo.Working –“. It doesn’t matter ifthe procedure exists or not, for the attacker won’t get that far. Theerror returned from this call is shown in Example 6.15.

Msg 916, Level 14, State 1, Line 1

The server principal "test" is not able to access the database

"model" under the current security context.

Example 6.15: Error message returned by an attacker running a stored proce-dure that doesn’t exist.

NoteWhy Are SQL Injection Attacks Still So Possible?

One major reason why SQL Injection attacks are still possible today is that there is so much bad information circulatingabout how to protect yourself from an SQL injection attack. For example, an article published by Symantec at http://www.symantec.com/connect/articles/detection-sql-injection-and-cross-site-scripting-attacks says that all you need to protectyourself is to verify the inputs using a regular expression that searches for the single quote and the double dash, as well asthe strings “sp” and “xp.” As you can see throughout this chapter, SQL Injection attacks can occur without tripping theseregular expressions, and considering the high number of false positives that looking for a single quote would give you(especially if you like doing business with people of Irish descent), the protection would be minimal at best. If you were toread this article and follow its instructions you would be leaving yourself open to SQL Injection attacks.

164 Chapter 6 SQL INJECTION ATTACKS

Page 17: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

The model database is an excellent database to try thisagainst, as typically no users have access to the model database.If the attacker gets an error message saying that the proceduredoesn’t exist, the attacker now knows that the login that theapplication is logging into the database has some high-levelpermissions, or the model database has some screwed-uppermissions.

After finding the username, the attacker can easily enough findthe name of the local database that the application is runningwithin. This can be done by trying to create a table in the data-base. This is because the error message when creating a tableincludes the database name. For example, if the attack code “’;create table mytable (c1 int);–” is sent, the error message shownin Example 6.16 will be returned.

Msg 262, Level 14, State 1, Line 1

CREATE TABLE permission denied in database 'MyApplicationDatabase'.

Example 6.16: Error message returned when creating a table when you don’thave rights returning the name of the database to the attacker.

These various values can be used in later attacks to clear thedatabase of its data or to export the data from the database.

Cleaning Up the Database After an SQLInjection Attack

There are a few different attacks that an attacker canperform against an SQL Server database. As shown so far in thischapter, delete commands can be passed into the SQL engine.However, other commands can be executed as well. Usually,attackers don’t want to delete data or take a system offline; theyinstead want to use the SQL database to help launch otherattacks. A simple method is to identify tables and columns thatare used to display data on the website that uses the databaseas a backend. Then extra data is included in the columns ofthe database, which will allow attacking code to be executedagainst the database. This can be done using an update state-ment that puts an HTML iframe tag into each row of a table.This way when customers view the website, they get the iframeput into their web browser, which could be set to a height of0 so that it isn’t visible. This hidden iframe could then installviruses or spyware on the user’s computer without theirknowledge.

Chapter 6 SQL INJECTION ATTACKS 165

Page 18: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

Once this attack has occurred and viruses or spyware havebeen installed on the customer’s computer, the most importantthing now is to stop additional users’ computers from beingattacked. This means going through every record of every tablelooking for the attack code that is pushing the iframe to thecustomer’s web browser. Obviously, you can go through eachtable manually looking for the records in question, or you canuse the included sample code, shown in Example 6.17, whichsearches through each column in every table for the problemcode and removes it. All you need to do is supply the variablewith the attack code. The only columns that are not cleanedby this code are columns that use the TEXT or NTEXT datatypes. This is because the TEXT and NTEXT data types requirespecial attention as they do not support the normal searchfunctions.

DECLARE @injected_value NVARCHAR(1000)

SET @injected_value¼ 'Put the code which has been injected here.'/)Change nothing below this line.)/

SET @injected_value ¼ REPLACE(@injected_value, '''', '''''')CREATE TABLE #ms_ver (indexid INT, name sysname, internal_value

INT, character_value VARCHAR(50))

INSERT INTO #ms_ver

EXEC xp_msver 'ProductVersion'DECLARE @database_name sysname, @table_schema sysname,

@table_name sysname, @column_name sysname, @cmd NVARCHAR

(4000),

@internal_value INT

SELECT @internal_value ¼ internal_value

FROM #ms_ver

FAQIFRAME versus PopUp

Often people ask if a popup blocker would prevent this iframe attack from affecting the end user, and theanswer is no, it wouldn’t. An iframe doesn’t show a web browser popup on the users screen. An iframe is an inlineframe which shows within the displayed webpage. An iframe with a height of 0 would be totally invisible to the enduser, but it could be requesting data from a webpage on another website, passing information from the user’scomputer back to this unknown website. The website that is called from the iframe could then exploit vulnerabilitiesin the end user’s web browser to install key loggers or command and control software turning the end user’scomputer into a member of a bot-net.

166 Chapter 6 SQL INJECTION ATTACKS

Page 19: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

DECLARE cur CURSOR FOR SELECT TABLE_CATALOG, TABLE_SCHEMA,

TABLE_NAME, COLUMN_NAME

FROM INFORMATION_SCHEMA.columns c

JOIN systypes st ON c.DATA_TYPE ¼ st.name

WHERE xtype IN (97, 167, 175, 231, 239, 241)

OPEN cur

FETCH NEXT FROM cur INTO @database_name, @table_schema,

@table_name, @column_name

WHILE @@FETCH_STATUS ¼ 0

BEGIN

SET @cmd ¼ 'SELECT NULL

WHILE @@ROWCOUNT <> 0

BEGIN

'IF @internal_value > 530000

SET @cmd ¼ @cmd þ ' SET ROWCOUNT 1000

UPDATE'ELSE

SET @cmd ¼ @cmd þ ' UPDATE TOP (1000)'SET @cmd ¼ @cmd þ ' [' þ @database_name þ '].[' þ @table_

schema þ '].[' þ @table_name þ ']SET [' þ @column_name þ '] ¼ REPLACE([' þ @column_name þ '], '

'' þ @injected_value þ ''', '''')WHERE [' þ @column_name þ '] LIKE ''%' þ @injected_value þ '%''

END'exec (@cmd)

FETCH NEXT FROM cur INTO @database_name, @table_schema,

@table_name, @column_name

END

CLOSE cur

DEALLOCATE cur

DROP TABLE #ms_ver

Example 6.17: T/SQL Code that will clean a database that has had its valuesupdated to send unvalued code to users.

NoteNotes About Using This Sample Code

Before running the included T/SQL code, be sure to make a full backup of the database in case of accidentaldata modification. The larger the database that you run this against, the longer it will take. When running this samplecode, it is recommended that you change the output type from the default output style of grid to text by pressing<cTRL>þT, in order to reduce the resources needed to run the query. The included code will execute against allversions of Microsoft SQL Server from version 7 to 2008 R2.

Chapter 6 SQL INJECTION ATTACKS 167

Page 20: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

SummarySQL Injection attacks pose some of the greatest dangers to the

database and customers because they are typically used todirectly affect the information that the customer sees and can berather easily used to attempt to push malicious code to clients’computers. These attacks are very popular with attackers becausethey are a relatively easy way to exploit systems design. They arealso popular because they are easy to reproduce once a site isfound to be compromisable, as it usually takes a long time tocorrect all the potential attack points in a website. This length oftime leaves the website and database open to attack for a longperiod of time as companies are usually unwilling to shut downtheir customer facing websites while the website design is beingrepaired.

Because of the way that the SQL Injection attacks work, theDatabase Administrator, Database Developer, ApplicationDeveloper, and Systems Administrator all need to work togetherto ensure that they are correctly protecting the data within thedatabase and the company network at large. As the database andapplication developers begin getting in the habit of writing codethat isn’t susceptible to SQL Injection attacks, the current project

NoteSQL Injection is Serious Business

In case you hadn’t guessed after reading this chapter, SQL Injection attacks are a very serious threat. Normally whenan SQL Injection attack is launched, it isn’t launched against a single website. An attacker will often write a problemthat will check as many websites as possible before the attacker is taken off the Internet. The last successful large-scaleattack on the Internet (as of the writing of this book) successfully changed the data in tens of thousands of separatedatabases that run tens of thousands of different websites. At the time of the attack, this was verified by searching onGoogle for the text of the code that was inserted into the attacked databases and looking at the number of domainsthat Google returned with matches.

Falling prey to these attacks puts users and customers at major risk, as these attacks often are trying to installviruses or Trojan horses on the end user’s computer, so that confidential data such as credit card numbers, and bankingusernames and passwords can be gathered by the attacker and used to commit future fraud against the users andcustomers of the attacked websites. This can lead to months or years of credit report problems and the like.

One final point to keep in mind: If you use your own company’s websites or services, then the SQL Injection attackeris attempting to attack you as you are also a customer. So do yourself a favor and protect the database so that youdon’t get viruses or Trojan horses installed on your computer through your own company’s website.

168 Chapter 6 SQL INJECTION ATTACKS

Page 21: SQL INJECTION ATTACKS - cdn.ttgtmedia.com · Many people think that SQL Injection attacks are a problem unique to Microsoft SQL Server, and those people would be wrong. SQL Injection

will become more secure, as will future projects that the teammembers work on.

SQL Azure is just as susceptible to an SQL Injection attack asany other SQL Instance. What the attacker can do within theinstance is much less dangerous simply because there are manyfewer features available. For example, protection againstxp_cmdshell isn’t a priority because xp_cmdshell isn’t availableon an SQL Azure instance. Neither are features such as databasemail or SQL mail, so protecting against attackers that plan to usethese vectors doesn’t need to be done. As time goes on, and morefeatures are added to SQL Azure, this may change; however, as ofthis writing, this information is accurate.

References“Wall Street Journal, Others, Hit in Mass SQL attackdSC Magazine US.” IT

Security News and Security Product ReviewsdSC Magazine US. N.p., n.d. Web.

October 21, 2010.

Chapter 6 SQL INJECTION ATTACKS 169