akersten 20 hours 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 20 hours 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 16 hours ago

    SVGs have a lot of security landmines; it's simplest to just disallow them, especially if they are untrusted (user provided)

    • tripplyons 16 hours 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 a day 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 a day 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 a day 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 a day 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.

      • ruined 20 hours ago

        use browsing containers to restrict access to specific contexts and this kind of thing basically can't happen

      • designerarvid a day ago

        Of course, by why not access those particular services in a more secure way? With other browser settings, another browser, or another machine altogether?

        Turning off JS permanently is like keeping your wallet in a safe you carry around all the time because once in a while you need to visit the dangerous parts of the town.

        • djoldman a day ago

          I have JS off by default and click one button to turn it on per website. You might be surprised how much faster the web is and how often you don't need JS.

          • zahlman 15 hours ago

            Yes, NoScript is great and I'm surprised how often HN users seem unfamiliar with the concept or need it justified to them.

  • drysart 18 hours 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.

  • VerifiedReports a day ago

    What security reasons (other than that cited by this demo, which doesn't seem to work on most platforms)?

  • paulpauper a day 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 a day 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)

  • est a day 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 a day 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 a day 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 a day 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

      • est a day ago

        > Why on earth would you want to load JS before content is loaded but not after?

        apparently, single-page-apps is an unstoppable trend. I tried to disable JS and 99% site won't work.

        But for content sites, after the article is loaded, disabling JS provides a much better reading experience.

        > but no one would choose that over the usability of Google Maps or OpenStreetMaps today

        That's a valid use for JS. But if you think about it, can we make a js free map tool using technics from OP's article? https://codepen.io/rebane2001/details/OPVQXMv

    • autoexec a day 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 a day ago

      Does JS protect against this particular attack? It seems like it's mostly implemented in CSS and SVG.

zahlman 14 hours 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 12 hours 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 12 hours 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 14 hours 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 14 hours 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.

      • bawolff 11 hours ago

        I think CSS just wanted to be able to apply filters (blur() is a very common use case). Since a filtering language already existed for svgs, and web browsers had already implemented it, it made sense to connect the two. SVGs can also be styled via css, so there needed to be a syntax to mark in document filters as applying to specific svg elements.

        I dont really think css filter is neccesary here though. I suspect the exploit could be implemented without that part just by embedding svg on the page.

PBnFlash a day 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 a day ago

The SVG adder is art. Love it.

  • cachius a day 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 a day 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 20 hours ago

    Yeah I had to turn off dark reader in firefox to see the examples "properly".

  • mzs 16 hours ago

    A zoom of not 100% breaks the QR one at least.

lambdaone a day ago

This is really impressive work. I'm not sure how this gets fixed, but it needs to be fixed, and soon.

timwis a day ago

What a cool post! Really enjoyed reading it.

scoofy a day ago

As someone who runs a site that uses inline SVG, this is unfortunate. Hopefully it won't be a problem for me.

  • pixl97 a day ago

    Maybe I'm missing something, but it looks like it requires an iframe attack or an XSS to work correctly, both of which have page/server settings that can be used to avoid them.

    • spartanatreyu a day ago

      It's easy to prevent clickjacking attacks by not allowing your website to be embedded in an iframe.

      You can do that by either adding a header to your network requests, o̶r̶ ̶b̶y̶ ̶a̶d̶d̶i̶n̶g̶ ̶t̶h̶e̶ ̶f̶o̶l̶l̶o̶w̶i̶n̶g̶ ̶m̶e̶t̶a̶ ̶t̶a̶g̶ ̶t̶o̶ ̶y̶o̶u̶r̶ ̶p̶a̶g̶e̶:̶

      ̶<̶m̶e̶t̶a̶ ̶h̶t̶t̶p̶-̶e̶q̶u̶i̶v̶=̶"̶X̶-̶F̶r̶a̶m̶e̶-̶O̶p̶t̶i̶o̶n̶s̶"̶ ̶c̶o̶n̶t̶e̶n̶t̶=̶"̶D̶E̶N̶Y̶"̶>̶

      EDIT:

      According to MDN, it will only work by adding it to your headers. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/...

bawolff a day ago

That's cool and all, but clickjacking is really overrated and its easy to address via x-frame-options. Most attack scenarios are very convoluted and impractical in real life (doubly so now that samesite cookies and cookie storage partitioning is now a thing).

Basically i dont think anyone should worry about this.

  • creata a day ago

    You're right that everyone should be using X-Frame-Options: DENY (for ancient browsers, plus CSP for newer browsers), but the author managed to pull it off on Google Docs. If even Google can't consistently stick to it, I feel like I should be worried.

    All website operators should read this imo: https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_...

    • frigateengineer a day ago

      > If even Google can't consistently stick to it

      Everything is a target. You can’t assume safety based on reputation or ubiquitousness.

      There are so many examples of the trusted well-used thing failing security to mention.

  • rebane2001 a day ago

    I don't think clickjacking is overrated, it's usually the opposite with it being not even accepted by many bug bounty programs.

    I've been able to make realistic attacks against multiple targets. Many services, such as Google Docs, need to enable cross-origin framing for their functionality.

    And beyond that, even if you restrict the framing, it might still be possible to clickjack as a part of a more complex attack chain, see: https://lyra.horse/blog/2024/09/using-youtube-to-steal-your-...

    And the attack in OP does not require iframes, so it can also be applied to injection attacks where CSP prevents javascript for example.

    (disclaimer: author of story)

    • bawolff 14 hours ago

      I hope im not coming off dismissive, this really is cool research.

      > it's usually the opposite with it being not even accepted by many bug bounty programs.

      As someone who has been on the other end of bug bounty's, its because clickjacking reports are a massive spam magnet. 99% of reported are not really vulns (e.g. no xfo header on a static website with no user auth, is not a vuln), and its just not worth sorting through.

      > I've been able to make realistic attacks against multiple targets. Many services, such as Google Docs, need to enable cross-origin framing for their functionality.

      The google docs thing is really cool. However i think services that need authenticated frames are few and far between. Now that cookies on frames tend to be opt in, i think the number of vulnerable services is going to go way down. Its not going to be 0, but its going to be pretty limited.

      • rebane2001 12 hours ago

        I don't think invalid spam reports mean something is overrated. Spam reports are spam reports. That'd be like saying buffer overflows are overrated because there are a bunch of AI-generated invalid spam reports with them.

        A valid report needs to demonstrate a realistic attack scenario, and I think that's the approach bug bounties should take.

        I think a good example is Google with its stance on open redirects[0]. They won't accept a report just pointing one out, but they will accept one that "can demonstrate that its impact goes beyond phishing".

        [0] https://bughunters.google.com/learn/invalid-reports/web-plat...

        • bawolff 11 hours ago

          I agree in the ideal scenario. However i think lots of bug bounties are understaffed and sometimes people make the pragmatic choice.

    • zahlman 14 hours ago

      > Many services, such as Google Docs, need to enable cross-origin framing for their functionality.

      What specifically does Google Docs do that requires it?

      > And the attack in OP does not require iframes

      How do you frame the victim site without iframes?

      • rebane2001 12 hours ago

        > What specifically does Google Docs do that requires it?

        Google wants documents to be embeddable on external sites.

        > How do you frame the victim site without iframes?

        You don't, you use it in a different scenario. For example if you have HTML injection, but its fairly limited due to strict CSP.

  • mdriley a day ago
    • cachius a day ago

      SVG and CSS filters can leak cross-origin data via iframes from March 6, 2025

      Researchers have observed that, in Chrome:

      A hostile webpage can create SVG or CSS filters that cover an iframe on the same page and act on the iframe's content.

      Specially-crafted filters can be created that vary their performance characteristics (different use of memory bandwidth or compute resources) based on input data.

      The induced differences in load can, in turn, be used to leak the input data through a timing sidechannel readable from Javascript.

paulpauper a day ago

A long time ago there was a facebook clickjacking method that could make someone inadvertently share a link or like a page. The former required clicking a combination of colored buttons and was quite clever. This was in 2010. But it could not do more, like steal sessions.

Aldipower a day ago

I want my Flash back! :-(