or
So, you say that OpenSSH is not secure...
No. I am not going to talk of what I believe to be OpenSSH security bugs or design flaws. Rather, I believe that OpenSSH is very good in these aspects. I am going to talk about its use. In fact, most security tools (including OpenSSH) ensure security as long as the user uses them correctly and understands what he/she is doing along with all the consequences of his/her actions.
For example, would you type this?
user@good$ scp -r ~/.ssh evil:foo/ |
If in ~/.ssh
you have some private keys, this copies them
to evil
. This also means that user@evil
and
anyone who can impersonate him/her can read the keys: this includes
the system administrator of evil
and, if
evil
has some security problems, every cracker that
breaks into that system.
Obviously, paranoia suggests that this is a bad thing, unless
you really trust root@evil
(pun intended) and
the security of evil
. Generally, it is better to avoid
trusting remote hosts and to be more paranoic about security.
What a silly example! I would never copy my private keys on another host!
Good. But what about this?
user@good$ ssh evil user@evil$ echo this is executed on evil this is executed on evil user@evil$ exit Connection to evil closed. user@good$ su Password: (you type your root password) root@good$ |
This may look good, but are you really sure you have not given
your root password to root@evil
? Are you sure that you
exited from ssh? What if the remote bash
(or
sshd
) is malicious? What if exit
is
interpreted as "print Connection to evil closed.
and
change the prompt to user@good$
"? What if even
su
is malicious?
Ok, I see your point. However, I work with the X Windowing System and terminal emulators and I always close my terminal after using OpenSSH.
Fine. Did you, perchance, enable the ForwardX11
option in
your ~/.ssh/config
?
Yes, of course! X forwarding is one of the coolest features of OpenSSH! Why did you ask that?
Because there is a reason for it being disabled by default.
Enabling X forwarding is OpenSSH, you allow remote clients to connect
to the local X sever. Thus, root@evil
can easily connect
his/her clients to your X server too.
Mmmmh... But why should that be dangerous? I do not care if he/she makes some windows pop up. Yes, it is annoying, but I would notice it immediately and it does not do any harm, does it?
An X client does not need to open a new window. Rather, it has full
unrestricted access to all the X resources, including the windows
created by other clients. For instance, it could take a screenshot of
the screen. This allows root@evil
to spy what you are
doing, reading your mail, etc. This is not good.
Alas, there is worse. Consider the following scenario with two X terminals in two separate windows:
user@good$ ssh evil user@evil$ echo hi hi user@evil$ | user@good$ passwd Changing password for user (current) UNIX password: |
A malicious client from evil
could ask to the X server
the list of all the windows, and find the window ID of the other
terminal easily. Then, it could ask the server to listen to the
keyboard events (such as key presses) for that window, thus reading
your password as you type it. The other terminal will still work,
since it is receiving the keyboard events too and you will hardly
notice that something nasty is happening.
This attack will work in most real-life cases and with most terminal emulators (AFAIK). Actually, some X terminal emulators provide a "Secure Keyboard" mode that prevents this attack by taking exclusive access to the keyboard. Since this mode is, IMHO, very inconvenient, most people (even who is aware of that mode) never use it.
Oh! That sounds quite bad. Are there any other concerns?
Unfortunately, yes. The malicious client could:
The last example is the most serious concern. Some clients (notably
xterm
) refuse keyboard events if they are sent by another
client. However, many clients do not do any check. For example, in the
following screenshot, a malicious client injects a command into a
terminal emulator (gnome-terminal).
In the example above, 0x28000c6
is the window ID of the
other terminal. The malicious command is executed by
user@evil
, but it could be executed by
root@evil
as well. In the user@good
window,
the user did not type anything: the command echo hi
was
"typed" by the malicious client on host evil
.
(Gulp!) Why the X server allows this to happen? Why the clients do not do any check?
Why should the server block it by default? Why the clients should?
This and similar features can be useful under a huge number of circumstances, both for the user and the programmer. Some applications must be able to take screenshots, for instance. Window managers deal with windows they do not own. Some applications "swallow" other windows into their own. And so on.
To block these operations by default would be too restrictive.
Ok, but what can I do to fix those security problems? I do not want to disable X forwarding over ssh!
If your X server support the X Security extension, there is something you can do. (Nowadays, most X servers do support it. For example, the popular XFree86 X server, has supported it since a long time)
The X Security extension can be used to run some X clients in a kind
of a sandbox, so that they have a restricted access to X resources
they do not own. This can be done using untrusted cookies
and xauth
. If you do not know how xauth
cookies work, please read the man page. In most setups, when you start
the X server a random number (the cookie) is generated and
stored in the file ~/.Xauthority
. That file is read by
both the server and the clients: when clients connect to the server
they send the cookie so that the server can check it and decide
whether to allow or to reject access.
However, there are different types of cookies. The one which is stored
in the ~/.Xauthority
file is (usually) a trusted
cookie. Using xauth
, you can create untrusted
cookies as well: clients that send to the server that cookie will be
granted a restricted access and will run in a sandbox. Here is how to
use it with ssh:
user@good$ xauth -f ~/.Xauthority.untrusted generate $DISPLAY . timeout 0 untrusted user@good$ XAUTHORITY=~/.Xauthority.untrusted ssh evil |
The last ssh
command forwards X connections, but uses the
untrusted cookie. Thus, the clients that connect from
evil
will use the untrusted coookie and will run in a
sandbox.
The command-injection attack does not work anymore.
As soon the malicious client sends a X_SendEvent
request,
the request is rejected by the server with a BadWindow
error. In fact, all "dangerous" requests are rejected with
some X error (the most common being BadAccess
) or, in
some cases, ignored and/or restricted.
So, using the X Security extension, I can run remote clients within a sandbox. Well-behaving clients will still run smoothly and malicious clients will be stopped. Am I right?
Almost. It depends on the definition of "well-behaved". If you define "well-behaved" client as a client that is never blocked by the Security extension, then currently most X clients are not well-behaved. This is because a client usually needs to interact with other clients for certain operations (as copy&paste, for instance), thus triggering some security constraint and receiving some unexpected error. Moreover clients are usually not prepared to deal with X errors and often die unexpectedly.
In the following example there are three terminals. The topmost is a
local client that runs OpenSSH and is connected to
evil
. As you can see, I launched an xterm
from it. The remote xterm
is the middle window. The
bottom window is just another local terminal. I selected some words in
the middle xterm
.
If I try to paste the "text to copy" in the bottom terminal, this is the result.
The xterm window suddenly closed. In the top terminal we can see it
received a BadAtom
error. This is because the
xterm
was going to send the selected text to the other
window with a X_ChangeProperty
request, and the X server
stopped it.
A lot of currently used X clients conflict with the sandbox: for
instance, GNU emacs
dies if you try to select some text,
netscape
dies immediately when starting and every
GTK+ 1.2
application dies when a menu is opened.
Therefore, if you use the X Security sandbox, do not be too surprised if X clients die unexpectedly.
The security policy seems too restrictive... Can I configure the security policy to suit my needs?
Unfortunately, the X Security extension policy is rather
fixed. Actually, there is a SecurityPolicy
file that
allows to configure some aspects of the policy, but it mainly deals
only with window properties and that can be not enough in many cases.
Argh! If I choose the safe way, I break compatibility with currently existing X applications. If I instead want compatibility I must give up security. What can I do?
You could use the X Supervisor extension
instead.
The X Supervisor extension is heavily based on the X Security extension and the sandbox it provides. In fact, it can be seen as an extension to the X Security extension.
Using it, you can run your untrusted clients in the sandbox provided by the X security extension. However, when a potentially dangerous request is received by the server from an untrusted client an X error is not sent to the client. Instead, a message is sent to a special client (the supervisor) and the untrusted client is put on hold. The supervisor examines the request and, according to its policy, tells the server to accept or refuse the request.
This approach has the following advantages:
Is that extension implemented in my X server?
No. This project is developing the final specification of the X Supervisor extension and its implementation for the XFree86 X server. It is still in development stage. However, a prototype has been completed.
Can you show to me that prototype "in
action"? For example, what does it do in the above example with
xterm
and the copy&paste?
Sure! Under the same situation (copying text from the middle
xterm
to the bottom local terminal), here is what happens
when using the current prototype:
A dialog appeared with some cryptic information and two Yes/No buttons. Since this is a prototype, the dialog is quite ugly and full of debug stuff useful only to its programmer, who is probably the only one that knows what the buttons do (but it is easy to guess).
However, cosmetic aspects aside, you can guess that the dialog is
telling us that some client asked the server to do something
potentially dangerous. The dialog actually shows the identity of that
client (the subject): it owns a window with ID
0xa0000e
and with name "user@evil -
xterm"
. It is obviously our xterm
. The dialog
also shows what the xterm
was going to do: a
ChangeWindowAttributes
operation on the object
with ID 0x80002c
. Alas, the prototype is not smart enough
to show that the object is nothing but the bottom terminal. This will
hopefully be implemented soon. The buttons are (you guessed it, didn't
you?) for accepting or rejecting the client request. If "No"
is pressed, an error will be sent to the xterm
, which
will likely die. If instead we accept the request by pressing
"Yes", the xterm
continues the copy&paste
operation. Actually, we must press "Yes" some more times for
the copy&paste to be completed, but after doing that, the string
"another text to copy" appears on the bottom terminal.
This is indeed a prototype: in the current form it is useful only to
people who know the X core protocol to some extent. While the
experienced X programmer can easily see that dialog and think
"the xterm
is setting the event mask on the bottom
terminal to 0x00400000
, thus listening for the
PropertyChange
events", the random Joe user can be
really confused at that sight.
There is still much work to do, both in the supervisor client (design a better and more useful user interface, implement a better policy, etc.) and in the server.
Last update: 24 Jul 2002 by zunrob