Re:Custom Properties as State
by brigandish on Saturday January 09, 2021 @12:38AM
(#25697632)
As I read I wondered about the possibility of its abuse as a payload system, then I reached this linked post[1]:
> What happens when you combine the fact that part after the : for CSS Custom Properties doesn’t need to be valid CSS with window.getComputedStyle()? You get a way of passing data – including Arrays, Objects, and even JSON – from CSS to JavaScript.
The first article proposes the possibility of sending updated variables via a CDN, and the linked one shows a CSS variable being parsed as JSON and then executed by the Javascript engine.
There's probably some fun and high jinks to be had there…
Re:Custom Properties as State
by capableweb on Saturday January 09, 2021 @06:46AM
(#25699599)
> Can you explain what the issue with this is?
The only issue I can think of is mixing code/data with styling information. Otherwise there is no "issue" per se.
> What does this circumvent that cannot be done with pure JS?
Nothing, it is just JS after all, and the idea that you can store data in other things than JS variables is not new (jQuery days we stored data in various attributes in the DOM to keep track of state). You could also store the same data in <title/> tag and get the same results. Not sure what the use case is, except it's a fun little hack.
Maybe this will spawn some new JS framework, nothing would surprise me anymore.
Re:Custom Properties as State
by dillondoyle on Sunday January 10, 2021 @03:20PM
(#25719215)
possibly a longer lasting cache 'super cookie' i made a poc comment below. you could do something similar with a dynamically generated js file but i might wonder if a very small css file with headers like a cdn is cached longer
Re:Custom Properties as State
by capableweb on Saturday January 09, 2021 @06:44AM
(#25699589)
It also shows a lack of understanding of how JS and CSS works in the browser. Disabling only JS would prevent anything from happen as CSS doesn't execute any code here, the JS part is responsible for that.
Except for enjoying a web without styles, there is no reason to disable CSS (together with disabling JS). You're not gonna prevent any more JS fudgery by having JS and CSS disabled compared to just JS disabled.
Re:Custom Properties as State
by brigandish on Saturday January 09, 2021 @07:38AM
(#25699865)
> It also shows a lack of understanding of how JS and CSS works in the browser.
Since you understand how a browser works much better than I do, tell me, can I disable XHR while still running JS?
From the article:
> CSS as an API?
> This makes me think that a CDN-hosted CSS file like this could have other useful stuff, like today’s date for usage in pseudo content, or other special time-sensitive stuff. Maybe the phase of the moon? Sports scores?! Soup of the day?!
> It’s almost like a data API that is tremendously easy to use.
Nope, I can't see any problem with JS being able to receive data from an external API, but then I have a lack of understanding of how JS and CSS work in the browser.
Re:Custom Properties as State
by scoopertrooper on Saturday January 09, 2021 @08:29AM
(#25700165)
Not OP, but disabling xhr is not possible and disabling it wouldn’t achieve much. The modern browser has many apis with which to make remote calls such as fetch, web sockets, and web rct. They can also fall back to classic methods like jsonp, crafty css skullduggery, and iframes.
The reason why this css thing is not a major problem is that the js could retrieve this data just as easily using one of the other methods I listed. JS retrieving data from an external API is generally not a problem unless its used for tracking purposes or as part of an cross site scripting attack.
At worst, this gives online tracking companies yet another tool in their toolbox. I am sure the boffins down at ublock are already working on detecting and mitigating this behaviour.
I can’t really see it being used for cross site attacks unless some whackadoodle site decided to try and send secreted authenticated data via CSS payloads.
Re:Custom Properties as State
by brigandish on Saturday January 09, 2021 @09:17AM
(#25700548)
> disabling xhr is not possible
uMatrix can do it, I'm sure there are others
> fetch
fetch is a Javascript API and covered by uMatrix's XHR setting[1].
> web rct
That can be disabled[2] and is also covered by uMatrix's XHR setting.
> iframes
Can be blocked in several ways, including the aformentioned uMatrix.
> At worst, this gives online tracking companies yet another tool in their toolbox
At worst CSS in the browser has had a CVE[3] and OWASP has some attacks[4] that seem old, but you know which of these have been fixed by all the browser vendors you use, right? Perhaps you've read this paper[5] on scriptless attacks and you know that all of these have been mitigated?
> The surprising result is that an attacker can also abuse Cascading Style Sheets (CSS) in combination with other Web techniques like plain HTML, inactive SVG images or font files. Through several case studies, we introduce the so called scriptless attacks and demonstrate that an adversary might not need to execute code to preserve his ability to extract sensitive information from well protected websites. More precisely, we show that an attacker can use seemingly benign features to build side channel attacks that measure and exfiltrate almost arbitrary data displayed on a given website.
Even better, you have the faith that there will never be a repeat of these kind of things and that no attackers will bother to go down this route in future. What part does faith have when deciding upon the risks of running things downloaded from untrusted sources?
Still, the anti-tracking is good enough reason for me.
> I am sure the boffins down at ublock are already working on detecting and mitigating this behaviour.
Re:Custom Properties as State
by capableweb on Saturday January 09, 2021 @08:11AM
(#25700080)
> can I disable XHR while still running JS?
Sure, but it's not easy. You'd have to run content-scripts from some browser extension that polyfills the APIs you want to get rid of. But disabling XHR/fetch/others won't stop your browser from being able to make requests. CSS can make requests (like when you provide custom font paths, or images), HTML can also make requests (<img> and <iframe> elements comes to mind). Without those, we don't have a web anymore, we have a document storage without links to other resources.
CSS cannot be used as an external API as much as HTML cannot be used as an API. The trick the author is talking about under "CSS as an API" assumes that JS is activated, otherwise you can't really do anything dynamic with the data. And if you're not doing something dynamic (like you wanna display some text in :content under a :before element), you can just set it in the HTML response instead of in the CSS response.
I'm not saying that disabling JS by default is bad (I do so myself, enabling it only for trusted sites). I'm just pointing out that disabling CSS is not gonna give you any additional benefits. As long as you're in the browser, a HTML page can make requests for you, even if you have CSS disabled.
Re:Custom Properties as State
by brigandish on Saturday January 09, 2021 @08:48AM
(#25700290)
> Sure, but it's not easy.
I have XHR disabled by default and can enable it with 2 clicks.
> But disabling XHR/fetch/others won't stop your browser from being able to make requests.
> CSS can make requests
Hence it being disabled.
> HTML can also make requests (<img> and <iframe> elements comes to mind).
Which is why I have those disabled by default too.
> CSS cannot be used as an external API as much as HTML cannot be used as an API
But it can be used as an API and because there are people out there, like yourself, who downplay this ability, there are those who will leave it running…
> assumes that JS is activated, otherwise you can't really do anything dynamic with the data
…and hence, may have disabled the usual routes that you listed - XHR, images, frames etc - and leave JS on for some other reason while believing they've mitigated a number of major threats.
It's hard to produce perfect security or anti-tracking behaviour, very hard, but that doesn't mean we should ignore CSS.
Re:Custom Properties as State
by Santosh83 on Saturday January 09, 2021 @07:26AM
(#25699793)
Blocking CSS turns most websites into unusable stream of text and oversized SVG images and such. At that point you may as well use something like Lynx or Wget...
Re:Custom Properties as State
by brigandish on Saturday January 09, 2021 @07:48AM
(#25699939)
I find it actually improves a number of websites (an increasing number), which may be more of a comment on the number of front-end devs who seem to be able to construct a website that degrades properly without javascript.
I also can't make Lynx and Wget into a more graphical form with just a couple of clicks, and there are other reasons reasons to disable CSS[1][2] but each to their own.
Re:Custom Properties as State
by dillondoyle on Saturday January 09, 2021 @01:32AM
(#25698005)
I thought the same thing....
classic cross domain ad tracking trick. BUT seems like chrome is trying to limit by keying caches to the domain. BUT BUT maybe not in cross domain web workers?
IDK though might be some interesting ideas. *edit maybe just cname cloak like are doing to get around itp
Re:Custom Properties as State
by dillondoyle on Saturday January 09, 2021 @05:40PM
(#25705744)
sure.
- basic js generates a css file with a random uuid and an example just my name. puts into a css var as a JSON object
- sets long term cache headers AND a matching etag (same as uuid)
- etag is a classic tracking trick but this is really cool it makes it accessible as state in JS client side
- index.html prints/logs the css var
- if css file is cached the uuid you see is static. no cookies needed
- i was also going to add just an array of recent request domains, last and first session. would help test the chrome cache keying. could even put a jwt in there
it's just a cool hack I never thought of. it's really cool how one thing can trigger an 'omg that's so obvious' brain fart.
Like even before CSS vars you could have done this just set really specific css width 12.999933/122.3333 or something then measure the div you set or maybe simpler just a random "'uuid_"+the_uuid_var+"'" classname add to body and then read if it exists with js. But I never thought of it until I saw this article!!! Same with just generating a JS file with static var which I've played with but never deployed. though I might guess a css file is cached longer? idk i don't have proof of that just a guess could be wrong
could maybe extend this to get around chrome cache keying with cname cloaking *edit actually maybe more likely that doesn't make sense idk i'd have to think about it
or just reading their docs last night about their new policy (only a couple months old) it looks like webworkers aren't enforced yet and you can explicitly control & cache a file with JS in a webworker
Re:Custom Properties as State
by bawolff on Friday January 08, 2021 @10:42PM
(#25696501)
I'm not sure what is so special about using css custom properties (aka css variables) as well, variables. That is their intended purpose after all, what else would you use them for?
In fairness the author talks about using them very dynamically (rip cache), which is a bit different, but still its just an extension of the basic idea of setting a variable.
Re:Custom Properties as State
by brundolf on Saturday January 09, 2021 @12:04AM
(#25697314)
One of the wonderful things about CSS is that because it's a domain-specific language, it can afford to be 100% declarative, with 100% deterministic behavior, and doesn't need any exceptions to be made or trap-doors to be added. The trap-door is JavaScript.
So, the more things you can move over into CSS, the more things exist in this beautiful pure context that's highly debuggable thanks to modern browser tooling (and that's not even getting into the performance advantages vs doing things in JS).
Put simply: it's really exciting every time CSS gets a new "real programming language" feature, even if these things are basic and familiar in other programming contexts. In this case we're not really getting a "new" feature, but people are used to thinking of CSS variables as like, a theming mechanism. I for one had never thought to use them as an API data format. The author is probing the boundaries of what's possible to do with them, and that's exciting and interesting.
As an aside: there's also a huge community that loves to just push and abuse HTML/CSS as far as they can for the sport of it. CSS-Tricks and its sibling-site CodePen are at the center of that community. To people like that, the idea of an API endpoint that uses a stylesheet to relay raw data for arbitrary usage is pretty cool.
Re:Custom Properties as State
by brundolf on Saturday January 09, 2021 @10:32AM
(#25701123)
Not if you don't add state/control flow. That's the key. That stuff is exiled to JS-land.
And by "state" I mean it in its proper sense: something where CSS itself can mutate its own state. The OP calls CSS custom properties "state", but they're really just "constants" in the context of CSS itself (they can only be mutated by JS).
Re:Custom Properties as State
by bawolff on Saturday January 09, 2021 @05:46PM
(#25705812)
I'd argue that css already has (very limited) control flow [calc() statements, and the cascading nature of selectors]. In combination with user interaction and html, it also has state.
Re:Custom Properties as State
by brundolf on Sunday January 10, 2021 @11:50AM
(#25716543)
CSS has expressions, but not imperative logic or mutability (it's possible I misused the term "control flow")
You're right that HTML (technically, the DOM) has a little bit of intrinsic state, despite our mental model of it being static. However that state is constrained to user interaction and is always very localized, so it avoids most of the maintainability problems that we think of as coming from having mutable state
Re:Custom Properties as State
by bawolff on Friday January 08, 2021 @11:49PM
(#25697182)
That's my point though, react has an actual song and dance. This is literally just using a feature literally named "variables" to store data, as if it was like a variable or something.
Re:Custom Properties as State
by bawolff on Saturday January 09, 2021 @12:31AM
(#25697570)
True, but you still cant do first paint until all css is loaded, and for people with fast connections, the latency of the extra roundtrip matters more than the size of the file downloaded (within reason)
Re:Custom Properties as State
by bryzaguy on Sunday January 10, 2021 @03:13PM
(#25719137)
An alternative would be keeping theme state in JS as suggested at the end of the article which improves the cache-ability of the css file as themes change.
Re:Custom Properties as State
by 1shooner on Saturday January 09, 2021 @11:29AM
(#25701695)
I don't understand the purpose of suggesting loading non-presentational state in CSS. The author says 'pseudo-content is even accessible these days', but inserting non-decorative content via CSS an explicit failure of WCAG 2.1 SC 1.3.1[1].
> What happens when you combine the fact that part after the : for CSS Custom Properties doesn’t need to be valid CSS with window.getComputedStyle()? You get a way of passing data – including Arrays, Objects, and even JSON – from CSS to JavaScript.
The first article proposes the possibility of sending updated variables via a CDN, and the linked one shows a CSS variable being parsed as JSON and then executed by the Javascript engine.
There's probably some fun and high jinks to be had there…
[1] https://www.bram.us/2020/03/30/pass-data-from-css-to-javascr...
I haven't tried this, but this should have the same effect:
The only issue I can think of is mixing code/data with styling information. Otherwise there is no "issue" per se.
> What does this circumvent that cannot be done with pure JS?
Nothing, it is just JS after all, and the idea that you can store data in other things than JS variables is not new (jQuery days we stored data in various attributes in the DOM to keep track of state). You could also store the same data in <title/> tag and get the same results. Not sure what the use case is, except it's a fun little hack.
Maybe this will spawn some new JS framework, nothing would surprise me anymore.
Except for enjoying a web without styles, there is no reason to disable CSS (together with disabling JS). You're not gonna prevent any more JS fudgery by having JS and CSS disabled compared to just JS disabled.
Since you understand how a browser works much better than I do, tell me, can I disable XHR while still running JS?
From the article:
> CSS as an API?
> This makes me think that a CDN-hosted CSS file like this could have other useful stuff, like today’s date for usage in pseudo content, or other special time-sensitive stuff. Maybe the phase of the moon? Sports scores?! Soup of the day?!
> It’s almost like a data API that is tremendously easy to use.
Nope, I can't see any problem with JS being able to receive data from an external API, but then I have a lack of understanding of how JS and CSS work in the browser.
The reason why this css thing is not a major problem is that the js could retrieve this data just as easily using one of the other methods I listed. JS retrieving data from an external API is generally not a problem unless its used for tracking purposes or as part of an cross site scripting attack.
At worst, this gives online tracking companies yet another tool in their toolbox. I am sure the boffins down at ublock are already working on detecting and mitigating this behaviour.
I can’t really see it being used for cross site attacks unless some whackadoodle site decided to try and send secreted authenticated data via CSS payloads.
uMatrix can do it, I'm sure there are others
> fetch
fetch is a Javascript API and covered by uMatrix's XHR setting[1].
> web rct
That can be disabled[2] and is also covered by uMatrix's XHR setting.
> iframes
Can be blocked in several ways, including the aformentioned uMatrix.
> At worst, this gives online tracking companies yet another tool in their toolbox
At worst CSS in the browser has had a CVE[3] and OWASP has some attacks[4] that seem old, but you know which of these have been fixed by all the browser vendors you use, right? Perhaps you've read this paper[5] on scriptless attacks and you know that all of these have been mitigated?
> The surprising result is that an attacker can also abuse Cascading Style Sheets (CSS) in combination with other Web techniques like plain HTML, inactive SVG images or font files. Through several case studies, we introduce the so called scriptless attacks and demonstrate that an adversary might not need to execute code to preserve his ability to extract sensitive information from well protected websites. More precisely, we show that an attacker can use seemingly benign features to build side channel attacks that measure and exfiltrate almost arbitrary data displayed on a given website.
Even better, you have the faith that there will never be a repeat of these kind of things and that no attackers will bother to go down this route in future. What part does faith have when deciding upon the risks of running things downloaded from untrusted sources?
Still, the anti-tracking is good enough reason for me.
> I am sure the boffins down at ublock are already working on detecting and mitigating this behaviour.
Let's hope so.
[1] https://github.com/gorhill/uMatrix/wiki/The-popup-panel#the-...
[2] https://www.ivacy.com/internet-privacy/disable-webrtc-leak/
[3] https://cve.circl.lu/cve/CVE-2011-0132
[4] https://owasp.org/www-community/xss-filter-evasion-cheatshee...
[5] https://www.nds.ruhr-uni-bochum.de/media/emma/veroeffentlich...
Sure, but it's not easy. You'd have to run content-scripts from some browser extension that polyfills the APIs you want to get rid of. But disabling XHR/fetch/others won't stop your browser from being able to make requests. CSS can make requests (like when you provide custom font paths, or images), HTML can also make requests (<img> and <iframe> elements comes to mind). Without those, we don't have a web anymore, we have a document storage without links to other resources.
CSS cannot be used as an external API as much as HTML cannot be used as an API. The trick the author is talking about under "CSS as an API" assumes that JS is activated, otherwise you can't really do anything dynamic with the data. And if you're not doing something dynamic (like you wanna display some text in :content under a :before element), you can just set it in the HTML response instead of in the CSS response.
I'm not saying that disabling JS by default is bad (I do so myself, enabling it only for trusted sites). I'm just pointing out that disabling CSS is not gonna give you any additional benefits. As long as you're in the browser, a HTML page can make requests for you, even if you have CSS disabled.
I have XHR disabled by default and can enable it with 2 clicks.
> But disabling XHR/fetch/others won't stop your browser from being able to make requests.
> CSS can make requests
Hence it being disabled.
> HTML can also make requests (<img> and <iframe> elements comes to mind).
Which is why I have those disabled by default too.
> CSS cannot be used as an external API as much as HTML cannot be used as an API
But it can be used as an API and because there are people out there, like yourself, who downplay this ability, there are those who will leave it running…
> assumes that JS is activated, otherwise you can't really do anything dynamic with the data
…and hence, may have disabled the usual routes that you listed - XHR, images, frames etc - and leave JS on for some other reason while believing they've mitigated a number of major threats.
It's hard to produce perfect security or anti-tracking behaviour, very hard, but that doesn't mean we should ignore CSS.
I also can't make Lynx and Wget into a more graphical form with just a couple of clicks, and there are other reasons reasons to disable CSS[1][2] but each to their own.
[1] https://medium.com/javascript-in-plain-english/tracking-with...
[2] https://www.templarbit.com/blog/2018/03/20/tracking-users-wi...
classic cross domain ad tracking trick. BUT seems like chrome is trying to limit by keying caches to the domain. BUT BUT maybe not in cross domain web workers?
IDK though might be some interesting ideas. *edit maybe just cname cloak like are doing to get around itp
poc: https://github.com/dillondoyle/css_cache https://dillondoyle.github.io/css_cache/index.html
- basic js generates a css file with a random uuid and an example just my name. puts into a css var as a JSON object
- sets long term cache headers AND a matching etag (same as uuid)
- index.html prints/logs the css var- if css file is cached the uuid you see is static. no cookies needed
- i was also going to add just an array of recent request domains, last and first session. would help test the chrome cache keying. could even put a jwt in there
it's just a cool hack I never thought of. it's really cool how one thing can trigger an 'omg that's so obvious' brain fart.
Like even before CSS vars you could have done this just set really specific css width 12.999933/122.3333 or something then measure the div you set or maybe simpler just a random "'uuid_"+the_uuid_var+"'" classname add to body and then read if it exists with js. But I never thought of it until I saw this article!!! Same with just generating a JS file with static var which I've played with but never deployed. though I might guess a css file is cached longer? idk i don't have proof of that just a guess could be wrong
could maybe extend this to get around chrome cache keying with cname cloaking *edit actually maybe more likely that doesn't make sense idk i'd have to think about it
or just reading their docs last night about their new policy (only a couple months old) it looks like webworkers aren't enforced yet and you can explicitly control & cache a file with JS in a webworker
In fairness the author talks about using them very dynamically (rip cache), which is a bit different, but still its just an extension of the basic idea of setting a variable.
So, the more things you can move over into CSS, the more things exist in this beautiful pure context that's highly debuggable thanks to modern browser tooling (and that's not even getting into the performance advantages vs doing things in JS).
Put simply: it's really exciting every time CSS gets a new "real programming language" feature, even if these things are basic and familiar in other programming contexts. In this case we're not really getting a "new" feature, but people are used to thinking of CSS variables as like, a theming mechanism. I for one had never thought to use them as an API data format. The author is probing the boundaries of what's possible to do with them, and that's exciting and interesting.
As an aside: there's also a huge community that loves to just push and abuse HTML/CSS as far as they can for the sport of it. CSS-Tricks and its sibling-site CodePen are at the center of that community. To people like that, the idea of an API endpoint that uses a stylesheet to relay raw data for arbitrary usage is pretty cool.
And by "state" I mean it in its proper sense: something where CSS itself can mutate its own state. The OP calls CSS custom properties "state", but they're really just "constants" in the context of CSS itself (they can only be mutated by JS).
For example see the css implementation of celluar autonoma http://eli.fox-epste.in/rule110/
You're right that HTML (technically, the DOM) has a little bit of intrinsic state, despite our mental model of it being static. However that state is constrained to user interaction and is always very localized, so it avoids most of the maintainability problems that we think of as coming from having mutable state
You'd have a separate theme.css that defined the new variables. Because of CSS variables you can keep the main style.css and all the markup the same.
[1]https://www.w3.org/WAI/WCAG21/Techniques/failures/F87