Ready to Start Your Career?

An Introduction to Cross Site Scripting

nullvyte 's profile image

By: nullvyte

September 14, 2015

An Introduction to Cross Site Scripting - CybraryWhat is Cross Site Scripting?Cross-site scripting (or “XSS”) is a vulnerability in web applications that's  caused by insecure coding practices, which do not sanitize user input. If a user of a vulnerable web application can pass scripts to the server and the server does not attempt to discover and remove scripts (“sanitizing input”), then the script can be executed in the context of the user's browser.XSS attacks can cause a web browser to be redirected to a malicious site, theft of a session ID, and even steal authentication cookies allowing an attacker to impersonate somebody else (including a web administrator) to gain access to otherwise restricted resources.There are generally three types of XSS attacks:
  1. Reflected (AKA non-persistent) XSS: this occurs when a script is executed on a one-time basis. Usually, this takes the form of a script injected into a URL, which is then passed to the target. When the target opens the URL, the script executes.
  2. Stored (AKA persistent) XSS: this attack occurs when a server is made to store a script such that when users visit the website, the script is executed in the context of the browser. The classic example of this type of XSS is when a malicious user finds a form on a site (such as a comment section or web forum) that stores content does not block the execution of scripts. They place the script in a comment or as a signature in their user account. Whenever the page loads the script is executed. A more nefarious example may be when a user enters a script into a “feedback” section of the website in order to execute a script inside the browser of an administrator who later reviews feedback messages.
  3. DOM-based XSS: this attack occurs by manipulating an existing script that's served to a user, such that the script executes on the client in a manner that's not anticipated. A DOM-based attack does not modify the source code of the website (as reflected and stored XSS do), but instead “tricks” the browser that receives the HTTP response to execute the code in a way that was not intended.
 How to Discover an XSS VulnerabilityReflected and DOM XSS attacks manipulate PHP or ASP files that are included as part of a website address. There are two basic methods of detecting these types of attacks. One of the simplest ways is to use a Google dork to find potentially vulnerable websites and then attempt to inject a script into the URL. The classic dork is inurl: “.php?id=”. The second method is to use a web application vulnerability scanner (such as WebScarab or Zed Attack Proxy).A stored XSS vulnerability is considerably harder to locate and requires either trial and error or a vulnerability scanner. In an environment where you're given permission to test a web application, the process requires that you map out all sources of input. These can include POST data sent to a site in forms, data sent or loaded via hidden forms, HTTP headers, etc. You must identify every input location and also the HTTP method required to pass that data.When you suspect a reflected or DOM-based XSS vulnerability, the standard proof of concept is to enter <script>alert('XSS')</script> in the appropriate location. You should have a web address that ends in something similar to .php?id=21. If the site is vulnerable, entering the Javascript alert after the = sign overwriting what was there originally will cause a dialogue box to open on the page with the text “XSS”. Using the above PHP file as an example, the end of the modified URL should read .php?id=<script>alert('XSS')</script>.In most cases, this basic test will not generate an error because there will be some attempt to sanitize user input and the <script> tag is such an obvious attack vector that most web applications attempt to block it. Input sanitization may be performed by either secure coding practices or the use of a web application firewall (WAF).Despite the ability to filter and remove scripts, XSS remains a significant vulnerability. This is due to the fact that there are a great deal of ways to bypass XSS filtering, whether it's performed by a firewall or is configured in the application source code.In the next section, this tutorial will explain several different techniques that can be used to bypass filtering technologies and execute scripts. How to Bypass XSS FilteringNot all of these techniques will work for any given application. Testing for XSS vulnerabilities is a trial and error process because you need to feel out what, if anything, is being filtered. You can manually try various bypass techniques or you can use a fuzzer. “Fuzzing” refers to the process of providing a wide variety of unexpected input to some application and observing how the application behaves.Typically, this requires the use of a tool to automate the process and provide the various input types to the application. This may take a short or long period of time depending on how comprehensive you make the process. OWASP's free tool Zed Attack Proxy includes the capability to fuzz web applications or entire websites. Remember to use the tool only against resources you own or have explicit permission to test.Common techniques to bypass script filtering involve encoding part or all of the injected script. There are basically two methods of encoding the script: URL and hex encoding.You can find URL or hex encoders online that you can use to encode any given script. Since web applications need to encode various parts of a URL (such as blank spaces in a search query), browsers can read encoded script content. If a firewall is not configured to check for the URL or hex encoded versions of these strings, they may be allowed to pass through. But, when the victim browser loads the content it will decode the script and execute it.Scripts can also be double-encoded (that is, encode the script and then encode the encoded script) to achieve the same results. Some firewalls will only check for single-encoded scripts, but most browsers can also read double-encoded content.Below is a list of various types of input that may bypass a filter to inject code and an explanation for why they work. This is by no means a comprehensive list of bypass techniques. OWASP maintains a very comprehensive list of techniques that may be used . All of the techniques below can be found on the site. Each technique listed here was tested by me against an Apache webserver under my control inside a VirtualBox hypervisor. The bypass: <SCRIPT>alert('XSS')</SCRIPT>Why it works: A WAF may have a rule to strip “<script>” whenever the tag is seen. Adjusting the case of the tag may work if the WAF rule is case-sensitive. You can also capitalize any random set of letters in each tag instead of capitalizing all letters. The bypass: <a onmouseover=alert('XSS')>Test link</a>Why it works: A WAF may filter out all <script> tags regardless of case. In this bypass, the victim will see a link on the website that was not placed there by the developer. If the user can be convinced to attempt to click the link, as soon as their mouse pointer hovers over the link, a dialogue box will pop up containing the text “XSS”. This is due to injection of Javascript's OnMouseOver function into the <a tag inserted into the URL. The bypass: <img onmouseover=alert('XSS')>Why it works: This code injects an invisible image that contains, as its data, the OnMouseOver function instead of a pointer to an image file. If the victim mouses over the location of the tag, the dialogue box containing the text “XSS” will pop up. The bypass: <img src=/ onerror=”alert(String.fromCharCode(88,83,83))”>Why it works: The <img> tag in this example is intentionally broken. By itself, this would only cause a broken image on the website. However, we have included the OnError, alert and String.fromCharChode Javascript functions and then encoded the letters XSS in decimal. The OnError function performs a specified action when an error occurs. Because the function is included in a broken <img> tag, OnError executes the subsequent code when the image fails to display. The rest of the code uses alert to generate a dialogue box and String.fromCharCode is employed to decode the decimal-encoded “XSS” letters. Encoding the letters as decimal values avoids a case where a WAF is filtering for the specific sequence of “XSS” or letters contained in a Javascript function. The bypass: <iframe src=script_location>Why it works: In this case you must replace “script_location” with an actual URL that points to a different website that runs a script. Here, we have generated an iframe in the HTTP response that's used to load a script from a different location. Because iframes are important tools in many web applications and may need to be used, there's a reasonable chance this technique can work. For some browsers, you need to malform the tag so the end bracket is open instead of closed. The bypass: <iframe src=alert('XSS')>Why it works: Similar to the previous example, iframes are common and may need to be used by web applications. In this case, we have loaded an iframe onto the page that executes the script instead of calling a remote script on a different website. The bypass: <body onload=alert('XSS')>Why it works: Here, we have injected the OnLoad function into a <body> tag. When the body of the site loads, the OnLoad function triggers the dialogue box. - Thanks and please post your comments and questions below. -
Schedule Demo