With Firefox on X11, any page can pastejack you anytime

Date: Tue, 17 Oct 2023 03:17:36 +0300 From: turistu To: oss-security@…ts.openwall.com Subject: with firefox on X11, any page can pastejack you anytime

Note to the moderator: I have already submitted this to the firefox people three weeks ago, and according to them, this is not a real security issue, or at least not worse than those pesky scripts which you cannot kill without killing firefox itself; if you think the same, just ignore this without replying.

I would however appreciate if you let this through and so give it some visibility so that the other 2 or 3 people who may be affected by this could learn about it.

Thank you very much.

====

In firefox running on X11, any script from any page can freely write to the primary selection, and that can be easily exploited to run arbitrary code on the user’s machine.

No user interaction is necessary – any page able to run javascript can do it, including e.g. a page from a background tab of a minimized window, an iframe inside such a window, an error page, a sandboxed iframe, a page that has reloaded itself via meta http-equiv=refresh, etc.

This applies to all the versions of mozilla/firefox and their derivatives (seamonkey, etc) that I was able to test, including the latest nightly.

Example

The simplest example, which works in the default configurations of systems like OpenBSD or Alpine Linux (= any Unix/Linux system where Wayland is not the default and the default shell does not implement bracketed-paste), would go like this:

Load the following snippet in firefox:


<span style="color:#323232;">
</span><span style="color:#323232;">intentionally left blank
</span>

Then pretend to forget about it, and go about your work. Sooner or later, when trying to paste something in the terminal with shift-Insert or middle click, you will end up running the command writeXPrimary() has injected just between your copy and paste.

live example of that snippet: turistu.github.io/firefox/pastejack.html

Short technical explanation

Browsers like firefox have the concepts of “secure context” (e.g. https://) and “transient user activation”; the javascript from the page gets some temporary powers as soon as you have interacted even so little with the page, like clicked, touched, etc.

For instance, writing with Clipboard.writeText() to the windows-style Ctrl-C Ctrl-V clipboard selection is only possible from secure contexts and only in the short while after the user has clicked a button, etc on the page. As this bug demonstrates, those prerequisites are not needed for writing to the primary selection, which on X11 is much more used and much more valuable.

Workaround

Without patching firefox, the only workaround I can think about is disabling the Clipboard.selectAllChildren() function from an addon’s content script, e.g. like this:


<span style="color:#323232;">let block = function(){ throw Error('blocked') };
</span><span style="color:#323232;">exportFunction(block, Selection.prototype, { defineAs: 'selectAllChildren' });
</span>

Complete extension here at github.com/turistu/odds-n-ends/raw/…/no-sel.xpi.

I tried to submit it to addons.mozilla.org but they didn’t accept it. If you’re running firefox-esr, the development edition or nightly, you can just set xpinstall.signatures.required to true in about:config and install it with firefox no-sel.xpi.

Firefox Patch


<span style="color:#323232;">diff -r 9b362770f30b layout/generic/nsFrameSelection.cpp
</span><span style="color:#323232;">--- a/layout/generic/nsFrameSelection.cpp	Fri Oct 06 12:03:17 2023 +0000
</span><span style="color:#323232;">+++ b/layout/generic/nsFrameSelection.cpp	Sun Oct 08 11:04:41 2023 +0300
</span><span style="color:#323232;">@@ -3345,6 +3345,10 @@
</span><span style="color:#323232;">     return;  // Don't care if we are still dragging.
</span><span style="color:#323232;">   }
</span><span style="color:#323232;"> 
</span><span style="color:#323232;">+  if (aReason &amp; nsISelectionListener::JS_REASON) {
</span><span style="color:#323232;">+    return;
</span><span style="color:#323232;">+  }
</span><span style="color:#323232;">+
</span><span style="color:#323232;">   if (!aDocument || aSelection.IsCollapsed()) {
</span><span style="color:#323232;"> #ifdef DEBUG_CLIPBOARD
</span><span style="color:#323232;">     fprintf(stderr, "CLIPBOARD: no selection/collapsed selectionn");
</span>

The idea of this patch was to always prevent javascript from indirectly messing with the primary selection via the Selection API. However, it turned out that the JS_REASON flag was not reliable; if javascript calls some function like addRange() or selectAllChildren() while the user has started dragging but hasn’t released the mouse button yet, that code will be called without that flag but with the text set by javascript, not the text selected by the user. However, I think that this patch is still enough to fill the glaring hole opened by selectAllChildren().

About the example and bracketed-paste

The bracketed paste feature of bash/readline and zsh means that you cannot just append a CR or LF to the payload and be done, it’s the user who has to press ENTER for it to run.

However, workarounds exist. For instance, some terminals like mlterm don’t filter out the pasted data, and you can terminate the pasting mode early by inserting a e201~ in the payload.

For bash, you can take advantage of some quirks in the readline library to turn off the highlighting and make the payload invisible to the user. E.g.:


<span style="color:#323232;">let payload = 'touch ~/LOL-' + Date.now() / 1000;
</span><span style="color:#323232;">writeXPrimary('n' + payload + 'n'.repeat(100) + ' '.repeat(30)
</span><span style="color:#323232;">	+ 'n'.repeat(100))
</span>

which will confuse the user with the same screen as when some stray background job had written something to the terminal:


<span style="color:#323232;">[email protected]:~$ : previous unrelated command
</span><span style="color:#323232;">[email protected]:~$	&lt;-- paste here
</span><span style="color:#323232;">#   &lt;-- cursor here, most users will just hit Enter to get a new prompt
</span>

live example of that snippet: [turistu.github.io/firefox/bash-pastejack.html

Just to be clear, I don’t think that either mlterm, bash, nor the shells that don’t do have that bracketed-paste feature are at fault here in any way (and I personally always turn off that misfeature as it badly interferes with my workflow): It’s firefox which should get all the blame for letting random javascript evade its pretended “sandbox” in this way.

About Wayland

For firefox running in Wayland, writeXPrimary() will only succeed when the firefox window (the main window, not necessarily the tab the code runs in) has the focus. Otherwise the selection will be cleared. At first I assumed that this is something specific to the Wayland protocol, but that turned out to be utterly false; it’s just some quirk, bug or “feature” specific to either firefox itself or GTK.

But I think that’s still bad enough, even if the page should take care to only set the selection when the main window has gained focus.

And of course, all this doesn’t affect the situation where you’re copying and pasting in another firefox tab with a different context, origin, etc; and all the other situations where you don’t appreciate having random javascript you don’t even know about messing with your copy & paste.

===

This is a slightly edited version of github.com/turistu/odds-n-ends/…/pastejack.md.

I will correct any errors or omissions and also add more info there.

qwool,

javascript shouldve only been used for changine element state and sending requests. anything more major, like mic access or custom players, would be sandboxed wasm that asks for permissions

ProgrammingSocks,

Wow am I glad for my NoScript usage right now. I’m definitely going to be even more restrictive after this.

smileyhead,

JavaScript was a mistake.

LufyCZ,

Yes, pure html pages are so much better and nicer to use!

smileyhead,

Not always 🤞. But most sites should be just documents + suggested styling. It really looks good and is super light.

Taian,

Must people also should only eat pineapples, they are tasty.

smileyhead,

Technical problems created by complicating the web to the point where only one/two companies in the world are able to maintain web browser is not a matter of taste.

schnurrito,

JavaScript has created a cross-platform world in which people can do most things without being locked into their OS. That is a good thing.

smileyhead,

A world where you cannot access bank, buy a flight ticket, do your taxes or rent a domain name without loading up propietary program on your machine that should be unnessesary.

I’m not against JavaScript as a whole. But those things should not require any additional app, regardles if compiled to assembly and running on Windows or compiled to JavaScript and running in Chrome. Anything above pure HTML should be optional and critical websites (like goverment) should work with scripts or styles disabled.

AnUnusualRelic,
@AnUnusualRelic@lemmy.world avatar

Case in point, in France we used to do all those things using a minitel terminal (which is about as bright as a VT100) and it worked fine (although at a slow 1200/75 speed).

schnurrito,

I don’t disagree with that at all. But better that it runs in the browser’s sandbox than that you have to install it to your machine which would work only under certain OS.

nyan,

And people wonder why my main browser profile restricts Javascript so tightly.

darcy,
@darcy@sh.itjust.works avatar

great explaination

ClemaX,

Maybe Firefox needs to add a new “Clipboard access” permission that can be granted on a site-per-site basis. When disabled, simple highlight and copy could still be enabled if hidden text cannot be added in between normal text.

The same permission model could be used system wide, but I do not think that such a feature exists on the X server or Wayland. Maybe using a wrapper that runs before the Desktop Environment?

stifle867,

While this is a real issue, the threat is best mitigated outside of the browser. In theory any application you run could put contents in your primary selection, the threat is what you do with that. The biggest threats I can imagine are insecure shell settings which the author pointed out and can be mitigated easily. Or as a commenter pointed out, cryptocurrency related activities could be at risk - such as pasting in an address to send the currency to could be hijacked and you probably wouldn’t even notice as the addresses are random. X is known to be insecure and if you’re doing something sensitive like handling cryptocurrency it would be best practice not to run X anyway.

Natanael,

A background service showing what you just copied might work for that, including one that could be set to automatically detect certain exanples of insecure clipboard content (hidden lines, weird Unicode, etc)

MigratingtoLemmy,

I’m not a web developer: is this a problem on Librewolf? Any settings I should be looking at?

stifle867,

It would be much easier to check the settings for your shell and display server. It’s a very niche threat. Think about how having something copied into your clipboard could actually effect you? I can’t imagine too many scenarios where you would paste something malicious that would actually be a problem. Paste something malicious into an email and you could just delete it. Paste something into the URL address bar and it wouldn’t submit until you told it to. Paste something malicious into your terminal and it wouldn’t submit until you hit enter (check that last one yourself).

Alternatively, disable javascript in the browser.

MigratingtoLemmy,

I think there is a way to paste commands into the shell which will run without me pressing the carriage return.

I do disable JS on websites I’ve never visited before, and the ones I allow to use JS, I attempt to audit the domains that need to run for the website to function.

chicken,

this is not a real security issue

This could be a huge security issue for anyone doing cryptocurrency stuff

possiblylinux127,

Xorg is a insecure mess

MonkderZweite,

Webbrowsers even more so.

BaumGeist,

If that’s true, I urge you to submit your findings to the relevant bug bounty program of whichever browser and at least get paid for all the hard work you’ve been doing

MonkderZweite,

Not a specific bug. But software who needs patches all few days to fix security holes is per definition insecure.

lemmyvore,

There’s one tiny little problem with the hijack scenario – people only ever paste from the primary selection immediately after selecting something themselves (and thus overwriting whatever was in there). That’s precisely because the primary selection is so easy to overwrite (basically when you select anything), so you want to select and then immediately paste so you don’t lose it.

So in reality this scenario in which a random page injects something in the primary selection and the user pastes it sometime later in a terminal, of all things, probably has like a million to one chance of occuring.

PS: Also, just for trivia, any user who’s been around the console for a while will hit Ctrl+C out of reflex when confronted with unexpected output, not Enter.

stifle867,

The included example script re-runs the selection every 500ms so it would instantly overwrite what the user has selected. In theory you could even lower this timer.

lemmyvore,

That doesn’t do anything to facilitate the attack, on the contrary. In order for the primary selection to work, the selected text must stay marked as selection until you paste, and everybody who uses primary selection has been conditioned to watch for that selection. If it were to suddenly dissapear you would assume you clicked somewhere by mistake, and attempt to select again, and again. You wouldn’t attempt to paste because you’ve been taught that the selection must hold in order to be able to paste. My next reaction would be to use the regular clipboard instead.

If anything, the script should attempt a longer retry, not a shorter one. A few seconds might be just right to catch someone after they’ve selected and are moving to the paste window, but before they’ve pasted the good text. But since the script is looping blindly and has no way to know when to inject, it would have to be a purely coincidental good timing.

I can’t imagine that this will manage to succeed very often.

stifle867,

It’s a simple POC. To address your points you could easily add an event listener for the window blur event so whenever the window loses focuses. You could also use javascript to manually highlight the user selected text when the window regains focus. You can make it as complex as you wanted.

The point is that the core of the issue, that you can override the users select buffer which could be used to maliciously insert commands, exists.

lemmyvore,

The Firefox window is not necessarily involved, the user could be copy-pasting between two other windows.

Look, I agree it’s annoying and it should be fixed. God knows Firefox is full of dumb little quirks that should have been fixed 10 years ago. But it’s not the gruesome attack vector it’s made out to be. It is a vector but not a great one, too many planets need to align for anything to happen.

stifle867,

I 100% agree that it effects an extremely small percentage of the population, but it’s also not hard to imagine a scenario in which this can have real consequences.

Let’s imagine I have a popular website that documents Linux tips and tricks (think: which command can I run to see drive storage used again?). In there I have a short command people can copy and paste to run (maybe df -h). The user copies this command and switches window to their terminal, at which point the blur event listener fires and I override the innocuous command with a malicious command. The user pastes it into their terminal without any indication that the primary selection content is now different.

Yes, this is due to both insecure X and shell settings that doesn’t effect everyone (Wayland and sane shell). It’s as much or even more the fault of the insecure programs, but Firefox is a part of that. Even in this situation it would be much more likely that the user is effected compared to the “general population”. It’s more of a targeted attack than a broad insecurity, but it’s not a “one in a million” chance.

aniki,

deleted_by_author

  • Loading...
  • juipeltje,
    @juipeltje@lemmy.world avatar

    Well wayland doesn’t work for me yet so… 🤷‍♂️

    aniki,

    deleted_by_author

  • Loading...
  • Infiltrated_ad8271,
    @Infiltrated_ad8271@kbin.social avatar

    There are many possible answers, but one far outweighs the rest: Nvidia.

    lightnegative,

    Nvidia and Barrier (or any software KVM). I need something cross platform that can share my keyboard and mouse between my Linux box and the crappy MacBook I’m forced to use for work.

    That’s Barrier currently but it only works on X11

    long_chicken_boat,

    Wayland is the worst thing that has ever happened to the Unix-like OSs. I’ll stick to X til I run out of programs that support it. And then, I’ll stick to the TTY and CLI programs.

    emax_gomax,

    Wayland is compatible with most X apps through xwayland. If you wanna avoid it then go ahead but pretending it’s not viable at all for anything ever is just stupid.

    long_chicken_boat,

    no. my problem with Wayland is that X worked on all POSIX compatible systems. But Wayland is Linux specific. Try running Wayland on Solaris.

    emax_gomax,

    Wayland what? Wayland is just a protocol. You need a wayland supporting client. If no ones ported one to solaris then that’s not waylands fault. Frankly I question how mature any of those options would be if they did. Seems plasma hasn’t had any solaris support for almost a decade, for example. It has migrated to wayland tho.

    jsdz, (edited )

    I tried to submit it to addons.mozilla.org but they didn’t accept it.

    It sort of looks as if they did accept it. If they were hesitant, perhaps it has something to do with the description suggesting that it’s a broken and pointless temporary kludge, as well as calling Firefox “removed”, and the ridiculously irrelevant screenshot.

    I didn’t realise it was that easy to build a simple firefox extension like that. Maybe I’ll modify it to disable the whole clipboard api and some other stuff.

    Thorned_Rose,
    @Thorned_Rose@kbin.social avatar

    Wtf is that screenshot?! When you're talking about user protection, it generally helps to have a relevant screenshot and not something thats going to confuse or put off users.

    clothes, (edited )

    Wow, you weren’t kidding! Makes me think it’s a sketchy add-on, even if it’s not.

    Pantherina,
    @Pantherina@feddit.de avatar

    Thanks! So when using the Firefox or Librewolf or Torbrowser Flatpak, make sure to disable X11 and X11 Fallback!

    iHUNTcriminals,

    How does one do this?

    Infiltrated_ad8271,
    @Infiltrated_ad8271@kbin.social avatar

    Search flatseal on flathub.

    Pantherina,
    @Pantherina@feddit.de avatar

    In KDE its in the settings

    donio,

    The last paragraph notes this is not X11 specific, Wayland is affected too it’s just that a bug prevents it from working when the FF window is not focused.

    avidamoeba,
    @avidamoeba@lemmy.ca avatar

    Are Chromium browsers affected by this too?

    hottari,

    Long answer: Chrome like every other application with a textbox will paste the text when copied from Firefox (bug originator). But you cannot trigger this bug from Chrome so…

    Short answer: No.

  • All
  • Subscribed
  • Moderated
  • Favorites
  • random
  • uselessserver093
  • Food
  • [email protected]
  • aaaaaaacccccccce
  • test
  • CafeMeta
  • testmag
  • MUD
  • RhythmGameZone
  • RSS
  • dabs
  • oklahoma
  • Socialism
  • KbinCafe
  • TheResearchGuardian
  • SuperSentai
  • feritale
  • KamenRider
  • All magazines