Readit News logoReadit News
akersten · 2 months ago
This is all solved by developers properly setting the X-Frame-Options header but I bet instead we'll delete half the SVG spec from the browser in some futile chase of security
rebane2001 · 2 months ago
it's not all solved because some applications require framing (eg google docs), and you can run this attack against a non-frame target, such a website with html injection, but strict CSP
umvi · 2 months ago
SVGs have a lot of security landmines; it's simplest to just disallow them, especially if they are untrusted (user provided)
tripplyons · 2 months ago
Definitely! In 2020, I reported an XSS vulnerability in GitLab using the onLoad attribute to run arbitrary JavaScript, and I was able to perform user actions without requiring any user interaction. For some reason it took them months to fix it after I reported it to them.
autoexec · 2 months ago
I already keep SVG disabled for security reasons, but it's increasingly looking like I'll have to find some way to disable CSS too. It's too bad people couldn't leave CSS alone as a nice simple (sort of) way to format text because turning it into another programing langue is begging for it to be abused by hackers and other malicious actors (like advertisers) just like JS
bawolff · 2 months ago
> It's too bad people couldn't leave CSS alone as a nice simple (sort of) way to format text

The base form of this attack goes back to the original CSS 1.

Honestly you are massively overreacting. This type of attack was much much easier to pull off in the late 2000s then it is now. Its basically impossible in practise now a days.

designerarvid · 2 months ago
Maybe I’m a too much of a normie to understand, but surely keeping your secure data away from your browser must be better than securing the browser to the point that it stops working?
notachatbot123 · 2 months ago
Any service that is exposed as a website that has data which you would like to keep secure = potentially hacked through attacks like these. It's usually not possible to choose to not have data available on internet connected services sadly.
drysart · 2 months ago
CSS isn't the security issue here. IFrames are the security issue; and have been since the first day they were added to a browser.
paulpauper · 2 months ago
nah, that is overkill. the probability of falling for this is still tiny and it cannot break the sandbox, steal session cookies, or anything like that .
autoexec · 2 months ago
Sandbox escapes are discovered all the time (pretty sure I've read about a few just this past week) and there are a lot of other problems CSS can enable (ads, fingerprinting, etc)
VerifiedReports · 2 months ago
What security reasons (other than that cited by this demo, which doesn't seem to work on most platforms)?
est · 2 months ago
why not disable javascript once and for all.

Most site shouldn't run any js after content is loaded.

I hope there's something like <body onload="js.disable()">

I can only do it manually in DevTool.

rebane2001 · 2 months ago
As a user: Browsers let you manually disable JS, but you can also use an extension such as NoScript (I do).

As a web developer: You can use Content Security Policy to limit or disable JS, as well as other resources such as CSS and images.

bawolff · 2 months ago
That's not relavent to the attack discussed in the article. These types of attacks do not involve javascript, nor could they due to the same origin policy.
pcthrowaway · 2 months ago
Why on earth would you want to load JS before content is loaded but not after? If you are able to assemble the page based on data sources before loading the page, you can just server-render the damn thing and disable JS altogether?

JS is essential for polished UX when you have highly interactive components. Technically mapquest got server-rendered interactive maps working, but no one would choose that over the usability of Google Maps or OpenStreetMaps today

autoexec · 2 months ago
I've got noscript which at least keeps JS off by default and allows me to selectively enable scripts by domain. Now I just a similar tool for CSS. Something that whitelists a sane set of features that can't be used (at least as easily) for interactivity, ads, fingerprinting, and other malicious activity while letting me explicitly blacklist annoyances (like scrollbar styles or sticky headers). The way things are going I'll probably need something similar for HTML too.
kg · 2 months ago
Does JS protect against this particular attack? It seems like it's mostly implemented in CSS and SVG.
zahlman · 2 months ago
> Let’s start off with a simple example - detecting if a pixel is pure black, and using it to turn another filter on or off.

I'm so lost, or at least, struggling. Why is modern HTML/CSS like this?

So there's apparently a hidden <checkbox>, and then a <label> "for" the checkbox that contains no text, but takes up space due to CSS properties. And also apparently clicking on the label toggles the checkbox because, it just works that way by default? And then the CSS properties can vary depending on the checkbox state, without JavaScript, because that's just built into CSS for some reason? And then in the second box, it's using another label for the same checkbox, so it shares that state.

Then the actual SVG... just defines filters, and doesn't actually draw anything. But the various demos get to pull filter definitions out of the SVG?

And two separate <feTile> tags define a filter in conjunction, one describing the region to take as a tile and the second describing where to tile it? Whereas all the other filters are just transforms on a common region? Why is it like that (as opposed to, say, having separate source and destination coordinates in the attributes for a single <feTile> tag)?

And what even are these <fake-frame> and <art-frame> elements?

rebane2001 · 2 months ago
> I'm so lost, or at least, struggling. Why is modern HTML/CSS like this?

I think it's pretty neat. It allows me to build cool interactive stuff such as the post in question without having to use JavaScript.

> And also apparently clicking on the label toggles the checkbox because, it just works that way by default?

Yes, that's how semantic HTML forms work.

> And then the CSS properties can vary depending on the checkbox state, without JavaScript, because that's just built into CSS for some reason?

Yes, it makes sense to be able to style an unchecked checkbox differently from a checked one. And I'm just using CSS's `:has()` to check for the state: html:has(#foo:checked) label[for=foo] { ... }

> And two separate <feTile> tags define a filter in conjunction, one describing the region to take as a tile and the second describing where to tile it?

<feTile> is a single element filter just like all the other ones. It just tiles the current image to the desired size. If the input is bigger than the output, it functions as a crop instead. So I use two of them to achieve a crop + tile.

> And what even are these <fake-frame> and <art-frame> elements?

They're autonomous custom elements, you can just make them up instead of using div-soup.

I touched on it in this post: https://lyra.horse/blog/2025/08/you-dont-need-js/

zahlman · 2 months ago
> <feTile> is a single element filter just like all the other ones. It just tiles the current image to the desired size. If the input is bigger than the output, it functions as a crop instead. So I use two of them to achieve a crop + tile.

Aha.

> I touched on it in this post: https://lyra.horse/blog/2025/08/you-dont-need-js/

I coincidentally was given that link elsewhere since posting and have been reading it and clarified much of the rest as well. Amazing work on the blog overall.

bawolff · 2 months ago
> I'm so lost, or at least, struggling. Why is modern HTML/CSS like this?

Most of the things you mention are not "modern"

> And also apparently clicking on the label toggles the checkbox because, it just works that way by default?

This goes back to the 90s. Clicking on a form widget label causes the widget to be focused.

I believe the original rationale is that is how desktop UIs do it. Also for checkboxes and radio buttons the hitbox would otherwise be quite small.

> And then the CSS properties can vary depending on the checkbox state, without JavaScript, because that's just built into CSS for some reason?

Well yes, if you want to customize the way checkboxes look you need to apply different styles depending on their state. Support for this literally goes back to version 1 of firefox.

> But the various demos get to pull filter definitions out of the SVG?

That's kind of a natural consequence of being able to embed SVG namespace elements directly in html. CSS supports it via the filter property, but i think even before that property existed you could probably do it via direct embedding svg in html or vice versa.

Anyways, my point is this isn't a situation of, what has modern html wrought. Most of this is very old features. I bet you probably could have done the same attack a decade ago.

zahlman · 2 months ago
> Well yes, if you want to customize the way checkboxes look you need to apply different styles depending on their state. Support for this literally goes back to version 1 of firefox.

It doesn't surprise me that this is possible for the checkbox, but it does surprise me that the label responds to the corresponding checkbox's state. (I take it that the styling is being applied to the labels, simply so that multiple labels can share state by all being "for" the same hidden checkbox.)

> That's kind of a natural consequence of being able to embed SVG namespace elements directly in html. CSS supports it via the filter property, but i think even before that property existed you could probably do it via direct embedding svg in html or vice versa.

I've only ever used SVG for... scalable vector graphics. I don't understand why CSS needs access. I get that SVG uses tags so that individual elements of the drawing can be in the DOM and then e.g. get animated by JavaScript. But I would have expected that to require JavaScript.

PBnFlash · 2 months ago
Reminds me of the flash player hack that would trick people into enabling system storage while hiding the menus. Vectors just can't help themselves
zephraph · 2 months ago
The SVG adder is art. Love it.
cachius · 2 months ago
Such a powerful demo. TIL I learned that functional complete is necessary but not sufficient for Turing completeness, for which you need storage and random access to it. Which you can probably implement somehow but not easily performant, and not in infinite dimensions.

https://stackoverflow.com/questions/4908893/what-logic-gates...

user_7832 · 2 months ago
Not sure if this is the same for others, but on my android chrome (technically kiwi browser, latest release), perhaps due to the inbuilt dark mode, stuff looks just "fine" or broken. Anyone else noticing such a thing?
williamscales · 2 months ago
Yeah I had to turn off dark reader in firefox to see the examples "properly".
mzs · 2 months ago
A zoom of not 100% breaks the QR one at least.
MatmaRex · 2 months ago
lambdaone · 2 months ago
This is really impressive work. I'm not sure how this gets fixed, but it needs to be fixed, and soon.