9

It's fairly well known that it's very dangerous to copy-paste text from a website into a terminal, as it can include extra text, control codes, and newlines that aren't visible when you're copying it, but which are saved into the paste buffer, causing malicious code to execute if pasted into a terminal.

The above-linked website contains the following HTML and CSS:

<p class="codeblock">
  <!-- Oh noes, you found it! -->
  git clone
  <span style="position: absolute; left: -100px; top: -100px">/dev/null; clear; echo -n "Hello ";whoami|tr -d '\n';echo -e '!\nThat was a bad idea. Don'"'"'t copy code from websites you don'"'"'t trust!<br>Here'"'"'s the first line of your /etc/passwd: ';head -n1 /etc/passwd<br>git clone </span>
  git://git.kernel.org/pub/scm/utils/kup/kup.git
</p>

This renders as git clone git://git.kernel.org/pub/scm/utils/kup/kup.git, but when you highlight and copy it, it pastes multiple lines into a terminal, causing them to be executed:

git clone /dev/null; clear; echo -n "Hello ";whoami|tr -d '\n';echo -e '!\nThat was a bad idea. Don'"'"'t copy code from websites you don'"'"'t trust!
Here'"'"'s the first line of your /etc/passwd: ';head -n1 /etc/passwd
git clone git://git.kernel.org/pub/scm/utils/kup/kup.git

Is there any simple, fast way to get around this for single-line strings? For example, copying the text, pasting it into the browser's search bar, and copying it from there seems to remove all newlines:

git clone /dev/null; clear; echo -n "Hello ";whoami|tr -d '\n';echo -e '!\nThat was a bad idea. Don'"'"'t copy code from websites you don'"'"'t trust!Here'"'"'s the first line of your /etc/passwd: ';head -n1 /etc/passwdgit clone git://git.kernel.org/pub/scm/utils/kup/kup.git

Now you would have to explicitly press enter in order to cause the code to execute, and the act of pasting it into the terminal is not enough. Is this a safe way to protect from all variants of this attack?

forest
  • 64,616
  • 20
  • 206
  • 257
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackexchange.com/rooms/124748/discussion-on-question-by-forest-simple-way-to-safely-paste-text-from-website-in). – Rory Alsop May 27 '21 at 08:51
  • related: https://security.stackexchange.com/q/113627, https://security.stackexchange.com/q/39118 – djvg Nov 05 '21 at 08:18

3 Answers3

2

Do you have a (GUI*) hex editor app available? Most of these are divided into two panes:

  • one that shows the raw bytes as groups of hex digits e.g. 48656C6C 6F20776F 726C642E
  • one that shows an interpretation of the bytes under some fixed-width character encoding like ASCII or ISO Latin-1 e.g. Hello world.

Paste the content in question in the right-hand (text) side of the hex editor. Like a text editor, this gives you a basic preview of all the characters which is a great start. But it has additional benefits beyond what a text editor has:

A good hex editor keeps a 1:1 relationship between the bytes on the left side and the text interpretation on the right. So if there are unprintable characters that get pasted in, you will be able to see gaps. Likewise for various Unicode tricks that might be used to hide content within a normal text editor.

So, assuming the website text isn't also capable of exploiting bugs in your particular hex editor (or the frameworks that editor uses), you get a more reliable view of the data, plus a head start on decoding anything malicious that might have been included!

* It is perhaps safe to paste into a terminal-based hex editor as well, but that seems like a separate Q&A diving into how the app putting data onto the clipboard, the terminal emulator itself, and the process(es) running inside the terminal all work together in the face of e.g. control codes and whatnot….

natevw
  • 131
  • 5
2

In vim I have this mapping:

nnoremap "<C-r>+", "<C-r><C-o>+"

CTRL-R CTRL-O {register}            *i_CTRL-R_CTRL-O*
        Insert the contents of a register literally and don't
        auto-indent.  Does the same as pasting with the mouse
        |<MiddleMouse>|. When the register is linewise this will
        insert the text above the current line, like with `P`.
        Does not replace characters!
        The '.' register (last inserted text) is still inserted as
        typed.
        After this command, the '.' register contains the command
        typed and not the text. I.e., the literals "^R^O" and not the
        text from the register.

For my zsh I have this plugin enabled: https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/safe-paste

The explanation of the zsh script: Preventing any code from actually running while pasting, so you have a chance to review what was actually pasted before running it.

SergioAraujo
  • 121
  • 4
  • Welcome to the community. Explaining approximately what the script does would be super useful. I'm guessing one of the things it does it removes newlines which stops execution of commands in the terminal for example. – Sir Muffington Jun 21 '22 at 20:50
0

I'm going to write an answer because comments would be too long, even though I'm not sure this is the answer you are looking for.

It sounds like you want a quick way to paste code into the terminal, yet I don't understand why you want to be quick when you are doing something that is clearly very dangerous, and it's also something that I suppose (and hope) you are not going to do too often. I mean, if you trust the source you can just copy and paste the code directly, but since you are clearly talking about sources that you don't trust (and which might use "tricks" to hide code inside text strings), why do you even want to be quick? You should actually want to slow down.

In the comments I suggested using a text editor to check the strings, but on second thought and after some tests I believe you can't even trust text editors in general after all. What can be done depends on the terminal (emulator) you use, and your text editor. My terminal apparently removes the escape character needed for ANSI codes from the command line, so I cannot use "invisible text" or move the cursor in the command (but it's possible of course to do this in the output). The following command can't be pasted for example, because the ANSI code is removed:

# ESC is 0x1B, the first code sets invisible text, the last resets it
echo foobar; ESC[8m echo hacked!; ESC[0m

If ANSI code worked, it would be possible to add invisible code at the end of a command, and then maybe move the cursor back to avoid the suspicious space before the prompt. Do all terminals behave this way? I don't know, but I don't think we should trust them all.

My terminal also removes the Unicode char U+202E (Right-to-left override) and U+202D (Left-to-right override). This means that the result might be going to be different than what you see and expect. For example:

 # The following string will appear as "echo rm;"
 # when seen in an environment that interprets those chars
 echo\u202E;\u202D rm

 # However when you copy it and paste it to an environment
 # that strips those chars off (like my terminal), you will get:
 echo; rm

It might be difficult to find tricks to execute arbitrary code, and what you can achieve might be limited, however it's still a sign that things can go wrong and newline chars might not be the only characters we need to worry about.

In fact, other chars we definitely need to worry about are non-ASCII chars that allow homograph attacks when URLs are involved. All modern browsers will show the real address today, but in a terminal I'm afraid there's no way to know what you are actually going to do before you hit enter:

# Here the first "e" is a Cyrillic letter
curl 'https://www.еxample.com'
Could not resolve host: www.xn--xample-2of.com

A text editor might or might not help in all cases (it depends on what it can display and how it is set up). A hex editor will always help, and it's probably what I would recommend: save the untrusted code in a file, then inspect it with a hex editor. Another quick solution could be be a custom script that makes sure all the input chars are printable ASCII chars, and if not, it warns you. You could use xclip for getting the input from the clipboard, grep for checking the input (if anything outside the printable ASCII range is found, print a warning, otherwise print a confirmation that the input is ok), notify-send or zenity to display desktop notifications. Configure some keyboard shortcuts to run it easily.

reed
  • 15,398
  • 6
  • 43
  • 64
  • The reason why I'd like a quick method (or like to know if the method using the browser search bar is effective) is for copying obviously-safe lines (think things like PGP fingerprints rather than complex lines of code) rather than typing them out manually. I'm aware of the issues with homoglyphs when URLs and similar identifiers are used. I actually _do_ have a program which sanitizes the X11 clipboard, but that's not a "simple way" which works on pretty much any system, so on other systems I currently copy entire fingerprints/hashes/commits by hand, which is a pain. – forest May 24 '21 at 23:37