Cross-Site Scripting: Reflected - http://zero.webappsecurity.com:80/join.asp?name=&email=&surname=&house="%20<~/XSS/*-*/STYLE=xss:e/**/xpression(alert(097531))>&street=&address2=&town=&postcode=&country=&homephone=&mobilephone=&msg=Please+fill+in+you
Created by: armorcodegithubpreprod[bot]
Category: Cross-Site Scripting: Reflected Instance Id: cc1fbd22-9848-44dd-87a3-b556a9b068df Vulnerability Id: "f3b005db-3fa8-46cb-b78f-afc5664bf147" Scan Type: Dynamic CheckType: Vulnerability Abstract: A Cross-Site Scripting vulnerability has been detected in Microsoft ASP.NET request filtering. Web applications that are coded in any .NET language and rely only on the default .NET request filtering are vulnerable to Cross-Site Scripting. If exploited, an attacker can manipulate or steal cookies, create requests that can be mistaken for those of a valid user, compromise confidential information, or execute malicious code on end user systems. Recommendations include implementing secure programming techniques that ensure proper filtration of user-supplied data, and encoding all user-supplied data to prevent inserted scripts being sent to end users in a format that can be executed. Request: GET /join.asp?name=&email=&surname=&house="%20<~/XSS/-/STYLE=xss:e//xpression(alert(097531))>&street=&address2=&town=&postcode=&country=&homephone=&mobilephone=&msg=Please+fill+in+your+name HTTP/1.1 Referer: http://zero.webappsecurity.com:80/join1.asp User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322) Accept: / Pragma: no-cache Host: zero.webappsecurity.com X-Scan-Memo: Category="Audit"; Function="createStateRequestFromAttackDefinition"; SID="2FB1253EFE4CBF0B674C1F3391A777E0"; PSID="62F0ACFFC03919EC68870F363A133936"; SessionType="AuditAttack"; CrawlType="None"; AttackType="QueryParamManipulation"; OriginatingEngineID="0c496fad-8e75-4ec3-9f78-382245e28eab"; AttackSequence="0"; AttackParamDesc="house"; AttackParamIndex="3"; AttackParamSubIndex="0"; CheckId="10639"; Engine="Query+Injection"; Retry="False"; SmartMode="ServerSpecificOnly"; AttackString="%22+%3c%7e%2fXSS%2f*-*%2fSTYLE%3dxss%3ae%2f%2fxpression(alert(097531))%3e"; ThreadId="25"; ThreadType="AuditDBReaderSessionDrivenAudit"; Connection: Keep-Alive Cookie: CustomCookie=WebInspect69383ZXB3FCEA2CCD6849B0A63D3EFF65615601Y3637;status=yes;username=;userid=;sessionid=;ASPSESSIONIDCARBTACT=HCEJMBECHJGCLEPIAAGODFHM;state=;passes3=;passes=;passes2=;Keyed=Var2=Second+Value&Var1=First+Value;Second=Oatmal+Chocolate;FirstCookie=Chocolate+Chip
Response:
Date: Fri, 13 May 2011 19:54:48 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Content-Length: 4027
Content-Type: text/html
Set-Cookie: passes=; path=/
Set-Cookie: passes3=; path=/
Set-Cookie: passes2=; path=/
Cache-control: private
<html>
<html>
<head>
<title>Join Us</title>
<STYLE>
<!--
td {font-size: 9pt; color: #FEFCE0; font-family: verdana, arial}
A:link {text-decoration: none; color: #FFFFFF;}
A:visited {text-decoration: none; color: #FEFCE0;}
A:active {text-decoration: none; color: #FFFFFF;}
A:hover {text-decoration: none; color:#CCFFFF;}
-->
</STYLE>
</HEAD>
<body bgcolor="#000066" bgproperties=fixed topmargin="0" leftmargin="0" marginheight="0" marginwidth="0">
<td valign="top" align="center">
<table width="100%" border="0" cellpadding="5" cellspacing="0" align="center">
<tr><td height="32" bgcolor="#c000ff"><center><b>J O I N</b></center></td></tr>
<tr><td>
<table cellpadding="0" cellspacing="2" border="0" width="400" align="center">
<tr><td> </td></tr>
<tr><td> </td></tr>
<FORM ACTION="join1.asp" METHOD="get" NAME="TheForm">
<center>
<tr><td bgcolor=#c000ff colspan='2'><b><center>Please fill in your name</center></b></td></tr>
<tr><td align="center" bgcolor=#003388 colspan='2'> </td></tr>
<TR><TD align="right" bgcolor=#003388><B>Name:</B> </TD><TD bgcolor=#003388><INPUT NAME="Name" TYPE="text" VALUE=""></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>Surname:</B> </TD><TD bgcolor=#003388><INPUT NAME="Surname" TYPE="text" VALUE=""></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>E-mail Address:</B> </TD><TD bgcolor=#003388><INPUT NAME="email" TYPE="text" VALUE=""></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>Password:</B> </TD><TD bgcolor=#003388><INPUT NAME="Password" TYPE="password" VALUE=""></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>Confirm Password:</B> </TD><TD bgcolor=#003388><INPUT NAME="Confirm Password" TYPE="password" VALUE=""></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>House Number:</B> </TD><TD bgcolor=#003388><INPUT NAME="house" TYPE="text" VALUE="" <~/XSS/*-*/STYLE=xss:e/**/xpression(alert(097531))>"></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>Street:</B> </TD><TD bgcolor=#003388><INPUT NAME="street" TYPE="text" VALUE=""></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>Address Line 2:</B> </TD><TD bgcolor=#003388><INPUT NAME="Address2" TYPE="text" VALUE=""></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>Town/City:</B> </TD><TD bgcolor=#003388><INPUT NAME="town" TYPE="text" VALUE=""></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>Postcode:</B> </TD><TD bgcolor=#003388><INPUT NAME="Postcode" TYPE="text" VALUE=""></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>Country:</B> </TD><TD bgcolor=#003388><INPUT NAME="Country" TYPE="text" VALUE=""></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>Home Phone:</B> </TD><TD bgcolor=#003388><INPUT NAME="homephone" TYPE="text" VALUE=""></INPUT></TD><TD></TD></TR>
<TR><TD align="right" bgcolor=#003388><B>Mobile Phone:</B> </TD><TD bgcolor=#003388><INPUT NAME="mobilephone" TYPE="text" VALUE=""></INPUT></TD><TD></TD></TR>
<tr><td align="center" bgcolor=#003388 colspan='2'> </td></tr>
<tr><td align="center" bgcolor=#003388 colspan='2'><b><a href="javascript:document.forms[0].submit()">Join</a></b></td></tr>
<tr><td align="center" bgcolor=#003388 colspan='2'> </td></tr>
<tr><td align="center" bgcolor=#c000ff colspan='2'> </td></tr>
</center>
</Table>
</table>
</body>
</html>
File Path: //zero.webappsecurity.com:0
Mitigation:
For Development:
Cross-Site Scripting attacks can be avoided by carefully validating all input, and properly encoding all output. Do not rely solely on default ASP.NET validation controls. In addition to using the default validation controls, properly sanitize all input parameters on server side applications by adopting a whitelist strategy to input validation. You may also validate input parameters directly in your code. Always use as strict a pattern as you can possibly allow.
Encoding of output ensures that any scriptable content is properly encoded for HTML before being sent to the client. This is done with the function HttpUtility.HtmlEncode, as shown in the following Label control sample:
Label2.Text = HttpUtility.HtmlEncode(input)
Be sure to consider all paths that user input takes through your application. For instance, if data is entered by the user, stored in a database, and then redisplayed later, you must make sure it is properly encoded each time it is retrieved. If you must allow free-format text input, such as in a message board, and you wish to allow some HTML formatting to be used, you can handle this safely by explicitly allowing only a small list of safe tags. Here are examples of how to do this safely:
C# Example:
StringBuilder sb = new StringBuilder(
HttpUtility.HtmlEncode(input));
sb.Replace("<b>", "<b>");
sb.Replace("</b>", "<b>");
sb.Replace("<i>", "<i>");
sb.Replace("</i>", "</i>");
Response.Write(sb.ToString());
VB.NET Example:
Dim sb As StringBuilder = New StringBuilder( _
HttpUtility.HtmlEncode(input))
sb.Replace("<b>", "<b>")
sb.Replace("</b>", "<b>")
sb.Replace("<i>", "<i>")
sb.Replace("</i>", "</i>")
Response.Write(sb.ToString())
Java Example:
public static String HTMLEncode(String aTagFragment){
final StringBuffer result = new StringBuffer();
final StringCharacterIterator iterator = new
StringCharacterIterator(aTagFragment);
char character = iterator.current();
while (character != StringCharacterIterator.DONE ){
if (character = = '<') {
result.append("<");
}
else if (character = = '>') {
result.append(">");
}
else if (character = = '"') {
result.append(""");
}
else if (character = = '") {
result.append("'");
}
else if (character = = '\') {
result.append("\");
}
else if (character = = '&') {
result.append("&");
}
else {
//the char is not a special one
//add it to the result as is
result.append(character);
}
character = iterator.next();
}
return result.toString();
}
The following recommendations will help you build web applications capable of withstanding Cross-Site Scripting attacks.
- Define what is allowed. Ensure that the web application validates all input parameters (cookies, headers, query strings, forms, hidden fields, etc.) against a stringent definition of expected results.
- Check the responses from POST and GET requests to ensure what is being returned is what is expected, and is valid.
- Remove conflicting characters, brackets, and single and double quotes from user input by encoding user supplied data. This will prevent inserted scripts from being sent to end users in a form that can be executed.
- Whenever possible, limit all client-supplied data to alphanumeric data. Using this filtering scheme, if a user entered "<script>alertdocumentcookie( 'aaa') </script>", it would be reduced to "scriptalertdocumentcookiescript". If non-alphanumeric characters must be used, encode them as HTML entities before using them in an HTTP response, so that they cannot be used to modify the structure of the HTML document.
- Use two-factor customer authentication mechanisms as opposed to single-factor authentication.
- Verify the origin of scripts before you modify or utilize them.
- Do not implicitly trust any script given to you by others (whether downloaded from the web, or given to you by an acquaintance) for use in your own code.
PHP: string htmlspecialchars (string string [, int quote_style])
ASP / ASP.NET: Server.HTMLEncode (strHTML String)
For Security Operations:
Server-side encoding, where all dynamic content is first sent through an encoding function where Scripting tags will be replaced with codes in the selected character set, can help to prevent Cross-Site Scripting attacks. The drawback to server-side encoding is that it can be resource intensive, and may have a negative performance impact on some web servers.
If site users must be allowed to use HTML tags, such as a bulletin board where the user would be allowed to use formatting tags, limit the ones that can be used. Create a list of acceptable tags, such as bold, italic or underline, and only allow those to be used. Any other tags should be rejected. Below are a few regular expressions that will help detect Cross-Site Scripting.
Regex for a simple CSS attack:
/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/ix
The above regular expression would be added into a new Snort rule as follows:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"NII Cross-Site Scripting attempt"; flow:to_server,established;pcre:"/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/i";classtype:Web-application-attack; sid:9000; rev:5;)
Paranoid regex for CSS attacks:
/((\%3C)|<)[^\n]+((\%3E)|>)/I
This signature simply looks for the opening HTML tag, and its hex equivalent, followed by one or more characters other than the new line, and then followed by the closing tag or its hex equivalent. This may end up giving a few false positives depending upon how your Web application and Web server are structured, but it is guaranteed to catch anything that even remotely resembles a Cross-Site Scripting attack. From a public perspective, you can also strengthen educational programs to help consumers avoid online scams, such as phishing, that can be utilized in account hijackings and other forms of identity theft.
For QA:
Fixes for Cross-Site Scripting defects will ultimately require code based fixes. The steps detailed in the Developer and Security Operations section will provide any developer with the information necessary to remediate these issues. The following steps outline how to manually test an application for Cross-Site Scripting.
Step 1. Open any Web site in a browser, and look for places on the site that accept user input such as a search form or some kind of login page. Enter the word test in the search box and send this to the Web server.
Step 2. Look for the Web server to respond back with a page similar to something like "Your search for 'test' did not find any items" or "Invalid login test." If the word "test" appears in the results page, you are in luck.
Step 3. To test for Cross-Site Scripting, input the string "<script>alert('hello')</script>" without the quotes in the same search or login box you used before and send this to your Web server.
Step 4. If the server responds back with a popup box that says "hello", then the site is vulnerable to Cross-Site Scripting.
Step 5. If Step 4 fails and the Web site does not return this information, you still might be at risk. Click the 'View Source' option in your browser so you can see the actual HTML code of the Web page. Now find the <script> string that you sent the server. If you see the entire "<script>alert('hello')</script>" text in this source code, then the Web server is vulnerable to Cross-Site Scripting.