Let's say you are following a guide on the internet and it provides a command for installing a package.
sudo apt install package
Without a second thought, you copy the command and quickly paste it in your terminal. Now imagine there was a different command in your clipboard, like this one:
sudo rm -rf /
*do not actually run this command!
This command forcefully and recursively deletes all your files and folders starting from the root directory. If you paste text containing a newline character in your terminal, it will automatically be executed. If your terminal has elevated permissions, because you already executed a sudo command in the same session, it will not ask for your password.
Goodbye precious data!
How can this happen?
There are three ways how websites can trick you into copying something else:
- By using the execCommand method from the Document interface
- By changing the clipboard data within the copy event
- By placing hidden and/or offscreen text within the visible text
The execCommand method
If you've ever copied a command from a website, you may have noticed that some offer a button that, once clicked, copies the command for you.
These buttons use the execCommand method from the Document interface. It is deprecated and can be removed at any time, but for now it is still working.
As the name implies, it allows you to execute a command. One of the commands you can execute is copy
. By executing this command you can copy the current selection to the clipboard.
An example is given below:
const hiddenInput = document.querySelector("input");
hiddenInput.value = "Text that should be copied";
hiddenInput.select();
document.execCommand("copy");
The tricky part is that malicious websites can have that button copy something completely different from what you are expecting.
So if you are on a website that you don't trust and you use one of these buttons, always double check what is currently in your clipboard by pasting it in a safe place, Notepad for example.
Changing the clipboard data within the copy event
Whenever you copy something using CTRL + C
or the context menu, a copy event is fired. A handler for this event can modify the clipboard contents using the following code:
const handleCopyEvent = (event: ClipboardEvent) => {
// Set the clipboard contents to a string of your choice.
event.clipboardData.setData(
"text/plain",
"sudo rm -rf /" // DON'T RUN THIS COMMAND
);
// Prevent the default action from overriding the data
// we just set.
event.preventDefault();
};
The code should be self-explanatory but if you want a more detailed explanation I recommend reading Stop Rashly Copying Commands From Websites by Louis Petrik, where I originally read about this exploit. It also includes an example and a link to a browser extension that I have created. More on that in a minute.
Placing hidden and/or offscreen text within the visible text
When you select text on a website it becomes highlighted. You would expect that the highlighted part is exactly what you are going to copy.
The problem is that, in some cases, invisible or offscreen text will also be part of your selection, even when it's not highlighted.
Some examples that hide text but still allow it to be selected are:
- Using
font-size: 0
- Moving text offscreen with absolute or fixed positioning
- Using absolute or fixed positioning in combination with
transform: scale(0)
Just to name a few.
There is an example that demonstrates this trick. The commands that you see there contain a span
that is moved offscreen.
How to protect yourself?
A good practice is to always double-check what is in your clipboard, by pasting it in a safe environment first. But what if your browser could warn you when your clipboard data is altered? How about a browser extension?
Meet Copy Guard
I have created a simple browser extension that does exactly that! It is called Copy Guard and its source code can be found on my GitHub. By using my extension you can let your browser warn you when a website is using the second or third method.
It injects a script which listens to the copy event. Whenever you copy something using CTRL+C or the context menu, it takes your current text selection and compares it to the data that is placed in your clipboard. Aside from that, it also checks if your text selection contains any hidden or offscreen elements.
Available for Chrome, Firefox and Edge.
A note on cryptocurrency
When I posted my browser extension on Reddit, I was told that stuff like this happens within the crypto community as well, which makes perfect sense. A website could have you copy a totally different wallet address. If you were to send your precious crypto to this address, it could be lost forever.
Something similar happened to a Reddit user once. Although this particular user probably had malware on their computer, it could also happen on the web, without any malware.
Conclusion
There are multiple ways how websites can trick you into copying something different from what you expect.
Always double-check your clipboard. My browser extension can at least warn you when something is fishy, but a good practice is to paste your selection in a safe environment first, before you paste it in your terminal.
At least do this for websites you don't trust.
Top comments (11)
Also keep in mind that in recent updated distributions
sudo rm -rf /
is blocked by the OSThat is good to know!
What is the copy event in HTML?
oncopy
?And if you can use the copy event to write data, can you use it to read data as well?
Yes,
oncopy
is the HTML equivalent.Reading is only possible within a
paste
event.Is it possible in a copy event, or no?
If so, do you know why they made the decision to leave out reading from copying events?
According to Mozilla docs, reading is not possible within the copy event. As for why it's disabled, I think the content is written to the clipboard AFTER the event is finished, because in order to change the clipboard data you need to cancel the events default action. So if you could read within the copy event, you would be able to read the old clipboard data, which is a security issue. I don't have any sources that confirm this however.
There is a way for websites to read the clipboard, which involves using the navigator. But if a website tries to do this, you will get a popup asking you for permission.
A previous team leader also warned of Unicode supporting editors and a toggle of hidden characters. Somehow being able to mark a sequence of characters as non-printing yet pasted into code, may still be valid code. I never explored it much but it still got me the habit of pasting code from external sources through a reduced character-set (ASCII) for validation.
This was really informational, so for that, you get a heart, AND a unicorn.
Thanks for the post.
This post caught me off guard tbh. fortunately never happened, but could've been me indeed.
Also, something worth mentioning during next retrospective:
'My clipboard ate my root folder'
When the "my dog ate my homework" excuse no longer works :D
Nice write-up and cool extension. I've made horrific mistakes with pasting into the terminal in the past.