Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Professional ASP.NET Security - Jeff Ferguson

.pdf
Скачиваний:
28
Добавлен:
24.05.2014
Размер:
13.26 Mб
Скачать

Treating the Client with Caution

1 3 SQL Injection - Microsoft Internet Explore!

 

 

 

 

HilEIj

 

File

Edit View

Favorites lools

Help

'.

' J -3

$

 

 

Jj Ba

 

 

 

 

 

 

Address ]*) htlp://loc*ost,'cn12/'SQLInji.Aspx

 

 

 

J

^Go

 

SQL Injection

 

3

I

Customer ID:

 

 

 

 

 

 

 

 

;

[ALFKI

 

 

 

Gel Customer Info

 

 

 

 

 

 

 

 

 

 

 

 

CustomerlD CompanyName

ContactName

ntactTitle

 

ALFKI

Alfreds Futterkiste Maria

es Representative

 

 

 

 

.......... ___ .... _______

fej Done

 

 

1J

 

 

^ Local intranet

A user might try to tamper with the SQL statement in order to receive an error message. If we don't handle the error properly, and if we expose the original error message to the user, they can gain more information about the SQL statement, and can start tampering with the SQL statement. For example, the user could enter:

ALFKI' or CustomerlD like '%

Since we don't perform any validation on the input provided by the user, the SQL string building statement will build the following SQL statement and execute it.

SELECT CustomerlD, CompanyName, ContactName, ContactTitle FROM Customers WHERE CustomerlD = 'ALFKI1 or CustomerlD like '%'

The result is that instead of seeing the specific information related to the current customer ID, all the information is exposed to the user. If the information shown on the screen is very sensitive, such as Social Security Numbers, date of birth, or credit card information, think of how much of an issue this could be!

41

Fte

£dit

View

Favorites

Joois

H

SQL Injection

Customer ID:

JALFKI' or customerid like '%

Get Cust

Cystornerl

CompanyName

ContactName

ContactTitle

 

 

 

 

ALFKI

Alfreds Futterkiste

Maria Anders

Sales Representative

ANATR

Ana Trujillo

Ana Trujillo

Owner

Emparedados y helados

ANTON

Antonio Moreno

Antonio Moreno

Owner

Taquen'a

 

 

 

AROUT

Around the Horn

Thomas Hardy

Sales Representative

 

 

 

 

BERGS

Berglunds snabbkdp

Christina Berglund

Order Administrator

BLAUS

Blauer See Delikatessen

Hanna Moos

Sales Representative

 

 

 

 

BLONP

Blondesddsl pere et fils

-rederique Citeaux

Marketing Manager

BOLID

Bolido Comidas

Martfn Sommer

Owner

 

 

 

 

i Done

The hacker can also enter ALKI' or 1 = 1 -- in the textbox. This will also have the same effect as above.

SELECT CustomerlD, CompanyName, ContactName, ContactTitle FROM Customers WHERE CustomerlD = 'ALFKI' or 1=1 --'

The two hyphens (--) is MS SQL Server's comment marker. The same technique can be used for My SQL with the hash (#) symbol, and with a semicolon (;) for oracle databases. The hacker can enter anything in the textbox, and if we don't validate it very well, then the database can come under attack.

SQL Union Attack

The attacker can also use SQL union statements to get more data. Even though the SQL union attack is very hard to carry out, it is certainly possible. For example, the main restrictions with the SQL UNION statement is that both queries should return the same number of columns, expressions, or aggregate functions, and the data types of the columns from the both queries should match. This makes the union attack a little harder to carry out, but after few tries the hacker can be successful. For example, the hacker can enter:

ALFKI' union select @@Servername

— This will generate a SQL statement like this.

SELECT CustomerlD, CompanyName, ContactName, ContactTitle FROM Customers WHERE CustomerlD = 'ALFKI' union select @@Servername --'

42

Treating the Client with Caution

-rhis will generate an error at the server and, based on your error handling mechanism, the error may or anv not be reflected to the hacker. After a few retries like this:

ALFKI' union select @@Servername, @@Servicename, @@Version --

ALFKI ' union select @@Servername , @@Servicename, @@Servicename, @@version --

the hacker will eventually be successful in their mission, and they find out how many rows are returned by the first SQL statement. This will give them more control over the second SQL statement that they are going to create using the union statement. For example, the above input will produce the following SQL Statement:

SELECT CustomerlD, CompanyName , ContactName, ContactTitle FROM Customers WHERE Customer ID = 'ALFKI' union select @@Servername, @@Servicename, @@Servicename, @@Version -- '

Since this is a valid SQL statement, SQL Server will execute the above statement and return the values back to the ASP.NET page.

'

SQL Injection

Customer ID:

'.'^Service

iria Anders

:i SQL Server 2000 - 8.00.194 (Intel X86) SQLSERV 4ug 6 2000 00:37:48 Copyright CO 1988-2000

Microsoft Corporation Personal Edition on Vlndows NT 5-0 (Build 2195: Service Pack 2)

ALR- I

SQL: SELECT CustomerlD, CompanyName, ContactName, ContactTitie FROM Customers WHERE CustomerfD = 'ALFKI1 union select @g>Servernarne, @@Servicename, ®)@>Ser»ioertame, ©©Version —'

..J

This output provides plenty of information about the server to the hacker including the server name, service name, version of the server including the service pack, and the OS version.

More Advanced Attacks

What we've seen so far is a simple SQL Injection, and all databases are vulnerable to this kind of attack. Let's look at a more advanced type of attack. Each and every database has its own strengths and weaknesses. For example, SQL Server lets us execute an external operating system command using the xp_cmdshell stored procedure.

The user can exploit this feature using the form field like this:

'exec master..xp_cmdshell 'net user HackUser MyPassword /ADD1--The

ASP.NET application will build the following SQL statement and send it to the SQL Server.

SELECT CustomerlD, CompanyName, ContactName, ContactTitle FROM Customers WHERE CustomerlD = ''exec master..xp_cmdshell 'net user HackUser MyPassword /ADD'--'

SQL Injection

Customer ID:

|_cmdshell 'net user HackUser MyPassword ^ADD'-- *

|g| Local intranet

When SQL Server receives this SQL statement, it will treat it as two separate statements in a batch, as follows:

SELECT CustomerlD,

CompanyName,

ContactName, ContactTitle

FROM Customers

WHERE CustomerlD =

''

 

 

 

exec master..xp_cmdshell

'net user

HackUser MyPassword

/ADD'--'

First, SQL Server will execute the select query, and will then execute the OS command, which will add the HackUser with MyPassword to the local System Account Manager (SAM). The rest of the SQL statement will be ignored, since it starts with the comment statement (--). If the ASPNET account is running with the admin privilege such as the sa account using SQL Server authentication, then this will happen without any problems since the sa account has sufficient privileges.

gj^jjgpg^g^gg|§[^nffgTB»"7^^i^^^MMaaaaaaMMKga[

Tree

^ Computer Management (Local)

B-ti! System Tools

• E

El System Information

a Performance Logs and Alerts

b~3 Shared Folders

J|| Device Manager

B|g Local Users and Groups

^i f c a r s

eg C3 Groups

Storage

d Disk Management

|Q^ Disk Def ragmenter i^a Logical Drives

i? jjgjj^ Removable Storage i l^i Services and Applications

iPt

JSK HackUsei

Full name-

Description:

f~ User must change password at next fogon f" User cannot change password

1™ Password never expires

!~" Account is disabled

r

---------

r~ .

 

 

 

 

|

OK

|

Cancel

 

j

 

:r>

 

44

Treating the Client with Caution

Validating, Encoding, and Filtering User Input

All these attacks are preventable, provided that we validate all data from un-trusted sources. When it comes to validating un-trusted data, we have to use several methods to make the input usable, including validating, encoding, and filtering the content. In this section we'll see how to process content before using it.

Validating Content

'Validate the user input before processing' is the mantra we have to remember if we want to avoid the types of attacks we've just been looking at. The validation could be anything from simple validation such as checking whether the entered value for 'Job Applicant Age" is a number, and is 16 or over, or making sure the username column has only valid characters such as A to Z, a to z, 0 to 9, and a few special characters.

The ASP.NET validation controls are an excellent way to validate content. In particular, the RegularExpressionValidator control is handy when validating user input. With regular expressions and the RegularExpressionValidator control, we can pretty much validate all kinds of data.

The advantage of using the validation controls is that we're defining the rules for the controls to decide what to allow and what not to allow.

Let's look at a simple example that uses regular expressions to validate username, US social security number, telephone number, and e-mail address.

<td><asp:TextBox id=txtUser runat=server MaxLength="20" /></td>

<asp:ReguiredFieldValidator id="RFVUser" runat="server" ControlToValidate="txtUser" Displays"Dynamic"

Font-Name="Verdana" Font-Size="lOpt">*</asp:RequiredFieldValidator> <asp:RegularExpressionValidator id="REVUser" runat="server" ControlToValidate="txtUser"

ValidationExpression="[A-Za-zO-9]{1,32}" Display="Static"

Font-Name="verdana" Font-Size="10pt">

Enter a valid user name. Only A-Z, a-z and 0-9 are allowed. </asp:RegularExpressionValidator>

<tdxasp:TextBox id=txtSSN runat=server MaxLength=" 11" /></td>

<asp:RequiredFieldValidator id="RFVSSN" runat="server" ControlToValidate="txtSSN" Display="Dynamic"

Font-Name="Verdana" Font-Size="10pt">*</asp:RequiredFieldValidator> <asp:RegularExpressionValidator id="REVSSN" runat="server" ControlToValidate="txtSSN"

ValidationExpre.ssion="\d{3}-\d{2}-\d{4)" Display="Static"

Font-Name="verdana" Font-Size="1 Opt">

45

If you don't have Unix or Perl programming experience, regular expressions could drive you crazy. Fortunately, Visual Studio .NET includes a number of commonly used regular expressions that can be used with the RegularExpressionValidator control.

French Phone Number

French Postal Code

German Phone Number

German Postal Code

If we use the CustomValidator control, it gives us the option to call the server-side validation function as well as the client-side validation function.

<asp: CustomValidator id="CVPwd" runat= "server" OnServerValidate="ServerSideFunction( ) " ClientValidationFunction="ClientSideFunction()

Since any one with a little JavaScript knowledge can understand our validation logic it is really not a good idea to use this. Therefore, be cautious when using the client-side validation function.

Filtering Input

When you've received incorrect input from an un-trusted source, it's not always practicable to refuse that input. In this kind of scenario, filtering the input is the best way. For example, let's suppose we want to filter out special characters such as the following: [ ] { } ; &.

To achieve this functionality, we're going to use the Replace method of the String object.

String sSearch = txtSearch.Text;

sSearch = sSearch.Replace("[" sSearch = sSearch.Replace("]' sSearch = sSearch.Replace("{" sSearch = sSearch.Replace("}" sSearch = sSearch.Replace (",-" sSearch = sSearch.Replace("&"

This code will replace all the unwanted characters from the users input. When we display the stripped version of the user input, we should see:

48

Treating the Client with Caution

F_fc

E*

Wen

Favorites

Tools

Help

*>B«k • •*

- (jjj Jj

4(

Jjsearch

 

^Favorites A#ress |f!?)

http://localhost/chl2;F*erng_CS.Aspx

Filtering Example

Search: |[{ )]

Search Term: nbsp

l5 Local Intranet

We can create this cleaning routine as a reusable method, and can use it against all kinds of data. Consider the following example:

String CleanUpInput(String strlnput)

strlnput = sSearch. Replace ("[ = strlnput sSearch. Replace! "] = strlnput sSearch. Replace ("{ = strlnput sSearch. Replace ("} = strlnput sSearch. Replace ( "; = strlnput sSearch. Replace ( "& = strlnput sSearch. Replace ("< = strlnput sSearch. Replace ( ">

//Return the clean data return strlnput;

Once this reusable method is built, we can use it from anywhere.

Encoding Input

Sometimes, the validated input might contain some illegal characters, or it might not always be viable to validate all user input. For example, in a search field, the user could type anything that they are searching for, including script tags such as <script>, script commands, such as alert, or HTML tags, such as <B>. In these cases, we can't always enforce a validation pattern. Encoding is the best way to neutralize harmful data from user input, since encoding translates the harmful characters into their display equivalents. For example the < character will be translated into < character. The HtmlEncode method of the Server object can be used to encode the harmful characters. Encoding characters that form the tags will prevent the tags they might form from executing. For example, let's say you've written an Online Form for programmers to exchange code and support each other. In this scenario, we have to allow members to show the code that fixes each other's problem. If we encode the content of the posting, users will be able to see the code, and the code will not be executed.

Consider the following example, in which we display the encoded search string in an ASP.NET label control.

void SearchDataStore(Object Src, EventArgs E)

IblSearchString.Text = Server.HtmlEncode(txtSearch.Text);

Search: <asp:textbox id="txtSearch" width="300" runat=server />

<asp:button id="btnSearch" Text="Search" OnClick="SearchDataStore" runat=Server /> <HR>Search Term: <asp:label id="IblSearchString" Text="" Runat="server" />

Now, when we enter some script, it will not execute, but will be handled as an inert character string:

 

Encoding Example

 

Search: [<script>alert('HiThere!);</script>

 

Search Term: <script>alert('Hi

 

There!');</script>

Encoding the

user input can prevent script injection attacks and preserves

the entered text

L.for display purposes.

Avoiding Cross-Site Scripting Attacks

Again, the only way to avoid cross-site scripting attacks is to validate users' input thoroughly before processing it. The first step in the anti-cross-site scripting attack precautions is to set the character set of the HTML output with the meta tag. If the character set is not specified in the HTML output by the web server, it can't determine which are the special characters. This will help the hacker to set a different character set and make all our validation code obsolete. The following example shows the use of Latin character set encoding (ISO-8859-1).

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-l">

</head>

The next defense against cross-site scripting is to validate user input. The best way to beat the cross-site script attack is to replace the special characters "% < > [ ] { } ; & + - - " ' ( )" with spaces. This can be done with the Replace method of the string object, or we can use the regular expression validator to exclude these characters at the input server control level.

50

Treating the Client with Caution

Once the special characters have been excluded, we can use the Server .HtmlEncode and Server . HtmlDecode methods. Here is a fixed example:

3 Encoding Example - Microsoft Internet Explorer

FJe Eds

View Favcrtes Tools

Help

* . B a c k -

• * - ' d j | | 3 - ^S e a r c h

Ajdress

|^j http://localtTOt/chl2/Enroding_Cs,Asp

Encoding Example

Search: <script>alert(This is cross-site attack);</script>

Search Term: <script>alert('This is cross-site attack1); </script>

..i

K LLii.ai intranet

The hacker could also enter the hex alternative of any character as input. For example, %3C and %3E are hex representations of the < and > characters. So the <Script> can be entered as %3Cscript%3E by the hacker. The Server .UrlEncode method can prevent his kind of attack. Unlike ASP, ASP.NET supports a Server .UrlDecode method that can be used to decode any encoded data.

For example, let's say the user enters something like:

%3Cscript%3Ealert('Hi');%3C/script%3E in

the textbox, which is equivalent to:

<script>alert('Hi');</script> We can use the UrlDecode and HtmlEncode methods of the

Server object to tackle this problem.

<HTML>

<HEAD>

<Title>Decoding Example</Title> <SCRIPT LANGUAGE="C#" runat=server>

void SearchDataStore(Object Src, EventArgs E)

{

IblSearchStr ing. Text = Server .HtmlEncode (Server .UrlDecode (txtSearch. Text) ) ; }

</SCRIPT>

</HEAD>

<BODY>

<h3>Decoding Example</h3> <FORM runat="server" Method="Post">

Search: <asp:textbox id="txtSearch" width="300" runat=server /> <asp:button id="btnSearch" Text="Search" OnClick="SearchDataStore" runat=Server /> <HR>Search Term: <asp:label id="IblSearchString" Text="" Runat="server" /> </FORM> </BODY> </HTML>

Here is what the output of the code will look like:

c-i

£cfc

View

Fawritec

look-

Help

Jj

Bacfc- » iMfeMfcitt) http //localhost/ch12yDecodinsLVB Aspx

Search: |%3Cscript%3Ealert('Hi}.%3C/scnpt%3E

Search Term: <script>alert('Hi');</script>

CjDone

Decoding Example

Disabling Active Scripting

As a consumer or user, we can disable the active scripting in Internet Explorer. Go to the Tools menu and select the Internet Options. Then go to the Security tab and select the Restricted Site option. Click the Custom Level button and scroll down to the Scripting section and select the Disable radio button for the Active Scripting option. Obviously, this means that no script will run, and relies on users to configure it.

J

 

 

General Security j Privacy] Contentj Connectionsj Programs]

 

 

 

 

 

 

 

 

OO

Advanced! Seiect a Web content zone to specify its security settings.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

O Enable

 

 

 

 

 

 

 

 

 

 

 

 

 

 

O Disable

 

 

 

 

 

 

 

 

Internet

Local intianet

Trusted sites

Restricted siies

 

 

 

 

 

 

 

 

 

 

 

 

 

© Prompt €J

 

 

 

 

 

 

 

 

Restricted sftet

 

 

 

Userdata persistence

 

 

 

 

 

 

 

 

 

 

 

 

© Disable

 

 

 

 

 

 

 

 

'am Web ^ites tha'

 

 

 

 

 

 

 

 

 

 

 

ia%> damage youf

 

 

 

O Enable []

 

 

 

 

 

 

 

""^ Lurnpu'er OF daia.

No ^

 

 

 

 

 

 

 

 

 

 

 

Scripting y^j Active

 

 

 

 

 

 

 

 

SwuiSy level foMhts zone

 

 

 

 

 

 

 

 

 

 

 

 

scripting

 

 

 

 

 

 

 

 

 

 

Custom settings.

 

 

 

 

 

 

 

J

 

 

 

 

 

 

 

 

© QQ^j

 

 

 

 

 

 

 

 

 

To change rhe settings, click Custom level - To use the

 

 

 

 

 

 

 

 

 

 

 

recommended settings, cbck Default Level.

 

 

O Enable O Prompt lj|} Allow

 

 

 

 

 

 

 

 

 

 

 

 

HP

w*

 

 

 

 

 

 

 

 

paste operations via script ©

 

 

 

 

 

 

 

 

 

 

 

 

 

R

 

Disable

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

e

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

s

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

et custom settings

 

 

 

 

 

 

 

 

- Reset to: High

Preventing SQL Injection Attacks

So, how might we prevent a SQL injection attack? The first step that we can take is to make use of the MaxLength attribute of the Textbox controls, thus restricting the number of characters the hacker can type. For example, if the Firstname textbox should only accept 40 characters, then we can enforce the length in the MaxLength attribute. This will restrict the hacker to sending small set of commands back to the server.

<asp:Textbox id="txtFirstname" MaxLength="40" runat="server" /> or:

52

Соседние файлы в предмете Программирование