meebey / smuxi

Smuxi is an user-friendly and free IRC client for Linux, Windows and Mac OS X based on GNOME / GTK+
https://smuxi.im/
GNU General Public License v2.0
171 stars 46 forks source link

Frontend listens on a random port on all interfaces #294

Closed infinity0 closed 1 year ago

infinity0 commented 1 year ago

Not sure why it has to do this. Potential security hole?

$ lsof -Pni | grep  LISTEN
[..]
Main         9029 infinity0   30u  IPv4    47564      0t0  TCP *:41731 (LISTEN)
[..]
$ ps aux | grep 9029
infinit+    9029  0.4  7.9 3650232 1304644 ?     Sl   Oct05  39:00 mono --debug /usr/lib/smuxi/smuxi-frontend-gnome.exe

I am using a non-SSH local "smuxi" connection.

meebey commented 1 year ago

The frontend has to expose a random port as part of the .NET remoting RPC. The behavior is not directly wanted by Smuxi but is expected if you a) use a smuxi-server and b) not using the SSH tunnel mode.

.NET remoting requires a TCP port on the server and client side if the server makes backcalls to the client. Microsoft was lazy to implement bi-directional communication using a single port... The frontend listening port does not expose unauthenticated objects or APIs. The frontend registers an object (that implements the IFrontendUI interface) with the smuxi-server. The smuxi-server then knows the object reference (I believe via memory address, not fully sure from my memory (no pun intended) though) and can make calls to the IFrontendUI object via that frontend port.

To reduce any potential attack surface smuxi wants the SSH tunnel mode by default, so it gives strong authentication, encryption and doesn't need any (non-localhost) exposed ports besides SSHd itself.

So to get rid of the *:41731 listening port I would recommend to enable the SSH mode, even though you may only connect "locally" on the same host.

infinity0 commented 1 year ago

OK, thanks for the explanation. Is it possible to at least switch it to listening locally only? On 127.0.0.1:x rather than *:x.

meebey commented 1 year ago

I have looked at the code to see how it decides the bind address and there is a small surprise as my suggestion to use the SSH mode would not do what I thought it would. If useSshTunnel==true, it does override the bindAddress to localhost only, but if the SSH hostname is localhost or 127.0.0.1 it skips that override and bindAddress becomes undefined which leads to "*" I assume.

Addding

bindAddress = "127.0.0.1";

to https://github.com/meebey/smuxi/blob/master/src/Frontend/EngineManager.cs#L161 might do the trick.

The code logic is a bit weird in there because it tries to make the SSH tunnel transparent to meet whatever .NET remoting tries to do...

meebey commented 1 year ago

.NET remoting seems to expect the bindAddress in a different property than machineName, but "bindTo": https://github.com/meebey/smuxi/blob/6d2c9fbbeaaa8731db2c3afb491dfc76bef9d15d/src/TcpChannel/TcpServerChannel.cs#L122

So adding

props["bindTo"] = bindAddress;

to https://github.com/meebey/smuxi/blob/master/src/Frontend/EngineManager.cs#L239 or similar is likely needed as well.

meebey commented 1 year ago

Setting props["bindTo"] does the trick:

Without bindTo:

meebey@Street-King> lsof -Pni | grep  LISTEN                                                                                          ~/Linux-Home/Projects/smuxi
...
mono-sgen 53547 meebey   26u  IPv4 0x91425b39e8aff25d      0t0  TCP *:56286 (LISTEN)
ssh       53576 meebey    6u  IPv4 0x91425b39e83f912d      0t0  TCP 127.0.0.1:7689 (LISTEN)

With bindTo:

meebey@Street-King> lsof -Pni | grep  LISTEN                                                                                          ~/Linux-Home/Projects/smuxi
...
mono-sgen 53890 meebey   26u  IPv4 0x91425b39ec85861d      0t0  TCP 127.0.0.1:57643 (LISTEN)
ssh       53899 meebey    6u  IPv4 0x91425b39e4041c3d      0t0  TCP 127.0.0.1:7689 (LISTEN)