[HN Gopher] Trick users and bypass warnings - Modern SVG Clickja...
___________________________________________________________________
Trick users and bypass warnings - Modern SVG Clickjacking attacks
Author : spartanatreyu
Score : 319 points
Date : 2025-12-05 00:03 UTC (22 hours ago)
(HTM) web link (lyra.horse)
(TXT) w3m dump (lyra.horse)
| autoexec wrote:
| 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
| paulpauper wrote:
| 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 wrote:
| 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 wrote:
| 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.
| autoexec wrote:
| 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 wrote:
| Does JS protect against this particular attack? It seems like
| it's mostly implemented in CSS and SVG.
| bawolff wrote:
| 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 wrote:
| 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 wrote:
| > 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
| rebane2001 wrote:
| 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 wrote:
| > 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 wrote:
| 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 wrote:
| 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.
| designerarvid wrote:
| 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 wrote:
| 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 wrote:
| Yes, NoScript is great and I'm surprised how often HN
| users seem unfamiliar with the concept or need it
| justified to them.
| ruined wrote:
| use browsing containers to restrict access to specific
| contexts and this kind of thing basically can't happen
| VerifiedReports wrote:
| What security reasons (other than that cited by this demo,
| which doesn't seem to work on most platforms)?
| drysart wrote:
| 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.
| scoofy wrote:
| As someone who runs a site that uses inline SVG, this is
| unfortunate. Hopefully it won't be a problem for me.
| pixl97 wrote:
| 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 wrote:
| 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, or by adding the following meta tag to your page:
|
| <meta http-equiv="X-Frame-Options" content="DENY">
|
| 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/...
| r1ch wrote:
| The modern way to do this is with the Content-Security-
| Policy: frame-ancestors directive:
| https://developer.mozilla.org/en-
| US/docs/Web/HTTP/Reference/...
| paulpauper wrote:
| 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.
| zephraph wrote:
| The SVG adder is art. Love it.
| cachius wrote:
| 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...
| bawolff wrote:
| 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.
| mdriley wrote:
| I tend to agree. See also:
| https://issues.chromium.org/issues/401081629
| cachius wrote:
| _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.
| creata wrote:
| 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 wrote:
| > 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 wrote:
| 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)
| zahlman wrote:
| > 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?
| bawolff wrote:
| 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.
| PBnFlash wrote:
| 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
| Aldipower wrote:
| I want my Flash back! :-(
| MatmaRex wrote:
| Reminded me of: https://lcamtuf.coredump.cx/css_calc/
| timwis wrote:
| What a cool post! Really enjoyed reading it.
| user_7832 wrote:
| 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 wrote:
| Yeah I had to turn off dark reader in firefox to see the
| examples "properly".
| mzs wrote:
| A zoom of not 100% breaks the QR one at least.
| lambdaone wrote:
| This is really impressive work. I'm not sure how this gets fixed,
| but it needs to be fixed, and soon.
| akersten wrote:
| 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 wrote:
| 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 wrote:
| SVGs have a lot of security landmines; it's simplest to just
| disallow them, especially if they are untrusted (user provided)
| tripplyons wrote:
| 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.
| zahlman wrote:
| > 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?
| bawolff wrote:
| > 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 wrote:
| > 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.
___________________________________________________________________
(page generated 2025-12-05 23:01 UTC)