Cross-Site Scripting (XSS)

Introduction

  • One of the most important features of a well-defended web application is data sanitization, a process in which user input is processed so that all dangerous characters or strings are removed or transformed.

  • Unsanitized data allows an attacker to inject, and potentially execute, malicious code.

  • Cross-Site Scripting (XSS) is a vulnerability that exploits a user's trust in a website by dynamically injecting content into the page rendered by the user's browser.

Types

  • XSS vulnerabilities can be grouped into two major classes:

    • Stored (aka Persistent): Occurs when the exploit payload is stored in a database or otherwise cached by a server. The web application then retrieves this payload and displays it to anyone who visits a vulnerable page.

    • Reflected: Include the payload in a crafted request or link. The web application takes this value and places it into the page content. This XSS variant only attacks the person submitting the request or visiting the link.

    • Either of these two vulnerability variants can manifest as client-(browser) or server-side; they can also be DOM-based.

    • DOM-based XSS takes place solely within the page's Document Object Model (DOM).

  • No matter how the XSS payload is delivered and executed, the injected scripts run under the context of the user visiting the affected page. This means that the user's browser, not the web application, executes the XSS payload.

  • JavaScript is a high-level programming language that has become one of the main components of modern web applications. All modern browsers include a JavaScript engine that runs JavaScript code from within the browser itself.

Finding XSS

  • We can find potential entry points for XSS by examining a web application and identifying input fields (such as search fields) that accept unsanitized input, which is then displayed as output in subsequent pages.

  • The most common special characters used for this purpose include: < > ' " { } ;

    • HTML uses "<" and ">" to denote elements, the various components that make up an HTML document.

    • JavaScript uses "{" and "}" in function declarations.

    • Single (') and double (") quotes are used to denote strings, and semicolons (;) are used to mark the end of a statement.

  • If the application does not remove or encode these characters, it may be vulnerable to XSS because the app interprets the characters as code, which in turn, enables additional code.

  • While there are multiple types of encoding, the most common we'll encounter in web applications are HTML encoding and URL encoding.

    • URL encoding, sometimes referred to as percent encoding, is used to convert non-ASCII and reserved characters in URLs, such as converting a space to "%20"

    • HTML encoding (or character references) can be used to display characters that normally have special meanings, like tag elements. For example, there is the character reference for "<".

  • We may need to use different sets of characters, depending on where our input is being included. For example, if our input is being added between div tags, we'll need to include our own script tags and need to be able to inject "<" and ">" as part of the payload.

  • We could leverage our XSS to steal cookies and session information if the application uses an insecure session management configuration. If we can steal an authenticated user's cookie, we could masquerade as that user within the target web site.

  • Cookies can be set with several optional flags, including two that are particularly interesting to us as penetration testers: Secure and HttpOnly.

    • The Secure flag instructs the browser to only send the cookie over encrypted connections, such as HTTPS. This protects the cookie from being sent in clear text and captured over the network.

    • The HttpOnly flag instructs the browser to deny JavaScript access to the cookie. If this flag is not set, we can use an XSS payload to steal the cookie.

Last updated