SSH client and bracketed paste mode

halfdog me at halfdog.net
Sat Oct 31 07:23:50 AEDT 2020


Hello list,

Using a terminal with bracketed paste mode (see [0], [1]), I
am not able to paste text while being in the "~C" command line
mode.

The reason for that is, that while being in that special mode,
openssh-client attempts to interpret the special bracketed paste
start escape sequence, which does not work:

root at localhost:~#
ssh> ^[[200~-L /home/..........long-path-to-socket:/run/....long-path-to-remote-socket
^[[201~Invalid command.
~
-bash: /root: Is a directory
root at localhost:~#

I tried to figure out, which of the three involved components
might be at fault. The component stack is:

* terminal
* local shell
* ssh
* remote shell

Just executing xxd on stdin instead with the stack

* terminal
* local shell
* xxd

the data copied and hexdumped did NOT contain the escape sequences,
only clipboard data was hexdumped. Hence I assume that for the
ssh-stack, the problem has to be somewhere between bash and ssh
interaction. This seems to be due to bash disabling and reenabling
bracketed-copy-paste while xxd running:

# bash disabling bracketed-copy-paste
64470 write(2, "\33[?2004l\r", 9 <unfinished ...>
...
64471 execve("/usr/bin/xxd", ["xxd"], ["SHELL=/bin/bash", ...
...
64471 +++ exited with 0 +++
...
# reenabling it after child exit
64470 write(2, "\33[?2004h", 8 <unfinished ...>


Instead on the ssh stack, local shell also disables bracketed-copy-paste,
but ssh or remote shell activates it again later on:

# Local shell disables it
72353 write(2, "\33[?2004l\r", 9)       = 9
...
# ssh is executed
72376 execve("/usr/bin/ssh", ["ssh", "...
...
# ssh login is completed
72376 write(5, "\r\nLast login: Fri Oct 30 17:51:32 2020 from 1.2.3.4\r\r\n", 58) = 58
...
# Ssh or remote shell activates bracketed-copy-paste, control
# sequence is written by ssh to local terminal-fd.
72376 write(5, "\33[?2004hroot at localhost:~# ", 38) = 38
...
# Later on ~C is called while bracketed-copy-paste is active
72376 write(5, "\r\n\33[?2004l\r\33[?2004hroot at localhost:~# ", 49) = 49
72376 select(7, [3 4], [], NULL, NULL)  = 1 (in [4])
72376 read(4, "~", 16384)               = 1
72376 select(7, [3 4], [], NULL, NULL)  = 1 (in [4])
72376 read(4, "C", 16384)               = 1
...
# Now copy and paste of ~C command content ("-L ...." string),
# that starts with the bracketed-copy-paste start sequence.
72376 write(7, "\r\nssh> ", 7)          = 7
72376 read(7, "\33", 1)                 = 1
72376 read(7, "[", 1)                   = 1
72376 read(7, "2", 1)                   = 1
72376 read(7, "0", 1)                   = 1
72376 read(7, "0", 1)                   = 1


Is this the intended behaviour?


If I understand it right, should ssh-client maybe track the remote
side activating and deactivating bracketed-copy-paste and then
a) when handling "~C" copy and paste doing it according to
bracketed-copy-paste or b) do not allow/perform special handling
of pasted data while in "~C", e.g. by deactivating bracketed-copy-paste
while in "~C" and reactivating it later on? Or should it c) be
completely agnostic to bracketed-copy-paste mode and make users
apply the non-intuitive "workaround" to again be able to copy-paste
the annoyingly long command path from my cheat sheet to an active
SSH connection?

root at localhost:~# cat > /dev/null

~C
ssh> -L /home/..........long-path-to-socket:/run/....long-path-to-remote-socket
Forwarding port.

^C
root at localhost:~#


Depending on the implementation decision, this might have a mild
security impact for the weird border case, where someone copy and
pastes input to a remote terminal, e.g. after reading seemingly
unproblematic commands on a webpage or in a mail. In worst case,
that could allow unwanted remote connections to the local machine
or with "PermitLocalCommand" execute commands on the client.

For the case where the remote machine is compromised, the admin
would need to copy and paste problematic text while seeing it, e.g.
by expanding an attacker-created file using tab expansion and
copy-pasting the file name then (or paste it while writing the
mail via ssh-connection) PLUS make use of the ssh-client induced
(maybe timing-related) transformation of the strings:

# touch $'PwnedReadme.txt\n\n~C\nhelp\n\n\n'
# ls Pw[tab]
... expands it
# stat 'PwnedReadme.txt

~C
help


'

Therefore the admin would be at fault copy-pasting such remote
content without review.

Other data-integrity issues would be pasting rare border cases like:

cat <<EOF > x.txt
hello
~C
help
more
EOF
xxd x.txt

which results in

# xxd x.txt
00000000: 6865 6c6c 6f0a 0a68 656c 700a 6d6f 7265  hello..help.more
00000010: 0a                                       .

Any opinions?

hd

[0] https://www.xfree86.org/current/ctlseqs.html#Bracketed%20Paste%20Mode
[1] https://cirw.in/blog/bracketed-paste

PS: I hope I did not mess up the text because I stumbled multiple
times over inadvertedly activating command mode when copy-pasting
the examples to this mail, written via ssh :-)



More information about the openssh-unix-dev mailing list