Cross-Site Scripting (XSS) continues to be within the OWASP Top 10 (an awareness document that is compiled with vulnerability statistics from security experts across the world). In the 2013 OWASP Top 10, XSS was number three but has since moved down to number seven due to browsers implementing controls to prevent the payloads from launching. While some browsers such as Chrome are continuously working to improve protection, others such as Firefox and Internet Explorer/Edge are trailing behind.
Some organizations use browser protection as a mitigating control, but that does not solve the underlying insecure coding issues and assumes every user uses the secure browser (e.g., Chrome) to access your site.
What is Cross-Site Scripting?
Cross-site scripting (XSS) allows attackers to execute scripts in the victim’s browser which can hijack their session, deface content, or redirect them to a malicious website. Cross-site scripting vulnerabilities occur when a parameter under the user’s control is either reflected (Type-2) to the user, stored (Type-1) and returned at a later time, or executed as a result of modifying the DOM environment (Type-0). A detailed run-through of each vulnerability will also be provided within the technical trenches section.
Reflected XSS is the type we most often see during our engagements, followed by Stored and then DOM.
Impact and Risk
There is a reason why it has been in OWASP for 2013 and 2017. XSS can have huge implications for a web application and its users. User accounts can be hijacked, credentials could be stolen, sensitive data could be exfiltrated, and lastly, access to your client computers can be obtained.
This section is geared towards application developers or system administrators who are seeking to understand why Cross-Site Scripting vulnerabilities exist, how they work, and how to properly mitigate them. For those not looking to get deep in technical details, you can skip to the Remediation section.
Types of Cross-Site Scripting
Below are thorough explanations and detailed walkthroughs of the different types of XSS. A vulnerable web application was set up for these examples. If you would like to recreate them, you can visit the DVWA website.
Reflected Cross-site Scripting
The form below is a simple form where your name is submitted. On submit, your name is echoed back to you.
XSS Figure 1
The query is run through a GET request using the name parameter.
XSS Figure 2
Note that this is the most basic exploit scenario. Some situations require prepending specific special characters to break out of specific functions to trigger the XSS.
Now that we know how to trigger the XSS, we can move the attack from a benign alert box to an attack worth mentioning by using this vulnerability to capture the authentication cookies of anyone that navigates to our vulnerable URL. The URL below will use the document.location to redirect a user to the vulnerable website while also appending the victim’s cookies.
If an authenticated user is coerced through phishing in opening the link above, their authentication cookies would be caught in the web access logs of the vulnerable website. Below is a snippet of what the attacker would see in their logs.
GET /cookiestealer.php?c=security=low; security=low; PHPSESSID=evqd9m6lhskh4d2ce7t3lrcsm5
From here, an attacker would only need to replace their cookie with the victims to obtain access to the victim’s account. The attacker would need to act fast as the authentication cookie could expire if the victim logs out or closes their browser.
The form below is a guestbook where a name and message are submitted and stored within the page. You can see where a Stored XSS vulnerable would be valuable here.
XSS Figure 3
The basic alert popup box technique of would work in an identical manner to the Reflected XSS above. The only difference is that the payload would launch when anyone navigates to the guestbook page. In the gif below, we input the payload, navigated to the page that contains the name form from the Reflected XSS attack scenario and then went back to the guestbook.
XSS Figure 4
Notice that the script is run as soon as the page is loaded. Attackers can now use this Stored XSS to obtain authentication cookies without requiring any coercion. Instead, they upload the payload to the guestbook and wait for visitors. Once the visitor navigates to the guestbook page, their cookie details can be immediately sent to the attacker. The visitor has now become the victim.
DOM-Based XSS (Type-0) is a form of XSS where the entire tainted data flow from source to sink takes place in the browser where the source of the data is in the DOM, the sink is also in the DOM, and the data flow never leaves the browser. For example, the source (where malicious data is read) could be the URL of the page (e.g., document.location.href), or it could be an element of the HTML, and the sink is a sensitive method call that causes the execution of the malicious data (e.g., document.write).
The form has a simple purpose where it is used to select your language. On submit, the default language is set and displayed in the URL.
In order to fully understand how this exploit will work, the source code of the form will need to be reviewed. Lines 4 and 6 below shows that data is read from document.location.href and passed to document.write().
XSS Figure 5
Note that the XSS payload was processed within the client and was not sent back from the server. This is the key difference between DOM-based and Reflected or Stored.
Cross-site scripting vulnerabilities exist due to the absence of two countermeasures – input validation and output encoding. Together, these controls restrict impact by sanitizing the user’s input to remove special characters and then encoding any remaining special characters before returning the content to the user.
Output Encoding: If special characters are required in the affected parameters, output encoding should be used to replace special characters with their HTML equivalent. (e.g., < becomes <)
Details of how to remediate each of the exploitation examples above will be shown below.
Replacing line 6 above with the following will present different results.
echo ‘Hello ‘ . htmlspecialchars($_GET[‘name’]);
The htmlspecialchars function will convert the predefined characters “<” (less than) and “>” (greater than) to HTML entities and disallow the XSS from loading.
XSS Figure 6
The source code of the example used above is below. The input is sanitized, but only for the “/” (forward slash) and “\” (backward slash). The mysql_real_escape_string prepares the data to be safely inserted into a MySQL query and does not prevent XSS.
Below is the HTML source of lines 6-10 above when the XSS was loaded.
Adding an additional line for htmlspecialchars to both inputs will again prevent the XSS from triggering.
$name = htmlspecialchars($name);
XSS Figure 7
The source code of the example used above is below.
For more specific recommendations, please consult the OWASP XSS Cheat Sheet.
How we can help
The Packetlabs team is composed of highly trained and experienced ethical hackers that focus and excel at detection and exploiting advanced vulnerabilities that are often overlooked and go undetected. Our team members have some of the highest regarded training when it comes to penetration testing including the Offensive Security Certified Professional (OSCP), Offensive Security Certified Expert (OSCE), GIAC Web Application Penetration Tester (GWAPT), and GIAC Exploit Researcher and Advanced Penetration Tester (GXPN) certifications. Contact us to learn more about how we can help.