[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [tor-dev] Restricting SOCKS access now and later (was Re: Proposal 351: Making SOCKS5 authentication extensions extensible)



Thanks so much for the thorough answer Nick. Looks like there are several potential solutions here. Responses inline below...

On 11/09/2024 14:12, Nick Mathewson wrote:
On Wed, Sep 11, 2024 at 7:02 AM Michael Rogers <michael@xxxxxxxxxxxxxxxx> wrote:

Hi Nick,

It would be useful to have a way of controlling access to the SOCKS port
so that untrusted applications running on the same device as a Tor
client can't use the Tor client's SOCKS proxy. This is something that
people auditing Briar have raised as a security concern.

Unix sockets aren't a great solution here because HTTP libraries don't
necessarily know how to connect to them. A TCP socket with
username/password auth is what HTTP libraries are expecting to see, but
because Tor uses the SOCKS username and password for other purposes, we
can't currently use them for access control.

Before seeing this proposal I'd thought about asking if Tor could
support some way of configuring username/password pairs, which would
function as real SOCKS credentials as well as providing stream
isolation. But it seems like this proposal would make that more
difficult, and if it's going to be possible to support SOCKS credentials
in future, it might make sense to plan for it now.

I'm not asking for username/password auth to be added to this proposal,
just for the proposal to leave room for it to be added in the future.

Can you see how that might be done?

Good question, Michael!

So, I see several answers: two comparatively simple, one a bit
trickier, one that's a bit philosophical, and two you probably can't
use.  (There are probably more I haven't thought of.)

In the order of descending usefulness:

## Simple answer 1: Extending this proposal to allow to using
username/password as a username/password

So, with this proposal (351), we have the ability to add new semantics
to the SOCKS5 username/password field: If the username begins with
`<torS0X>`, then the next byte describes what format the rest of the
username/password are in.

Now, the version of this proposal sent to the ML only defines
semantics for `0`; there's a version on gitlab (see [torspec!280])
that defines both `0` and `1`.

[torspec!280]: https://gitlab.torproject.org/tpo/core/torspec/-/merge_requests/280

But we could also add a new format (call it `P`) that allows encoding
an actual username and password.  That would be backward compatible
with this proposal, though we'd actually need to design and implement
it.

To use such a format, you might configure the SOCKS library to say
that the username is something like `<torS0X>Pmy_real_username`, and
that the password is `cnffjbeq`.

(FWIW, I believe this proposal makes it _easier_ to put a
username/password back into the SOCKS5 username password field, since
it defines a forward-compatible way to define new implementations.)

This sounds promising to me. I wasn't sure if the format byte was meant to act as an incrementing version number, with the expectation that new formats would supersede old formats and support for old formats would eventually be dropped. If there's an expectation of keeping multiple formats in use indefinitely to serve different purposes then that's great news and it seems like we could define a username/password format as you've suggested, without needing to hold up this proposal with the details.

## Simple answer 2: Define a new SocksPort where Username/Password
means Username/Password

Both C Tor and Arti have the ability to define flags on a SocksPort.
We could in principle define a flag that means, "On this particular
SocksPort, Username/Password authentication is required, prop351
semantics are not available, and the username/password must be on some
list of approved users."

(Again we'd need to actually design and implement this, but it's not
impossible.)

This would also work for our purposes and was roughly what I'd had in mind to suggest before seeing this proposal. However it would depend as you mention below on whether we also needed/wanted to use RPC session IDs.

## Trickier answer: How to do it if your application is using Arti RPC

With the Arti RPC subsystem (that's Arti's equivalent of C Tor's
control port), when your app authenticates an Arti RPC connection, it
gets an Object ID for an object called a Session.  According to this
proposal as amended at [tospec!280], you open a SOCKS connection
within a session by setting your username to
`<torS0X>1session_id_goes_here`.  (Note that Session IDs are fairly
long, and deliberately hard to guess.)

Taken together, this would make it possible to add a SocksPort flag
that means "Don't allow any SOCKS connections unless they are on a
session."

With this flag, if your application is already authenticating with
Arti RPC and linking its sockets via the mechanism defined here, it
would be allowed to connect, but Arti would shut out any application
that wasn't configured to do so.

Seems to me that this would also solve our problem, although if sessions IDs are being used as capabilities then maybe it would be good to make it an explicit part of Tor's threat model that session IDs must not only be hard to guess, but should be treated as confidential (not logged, etc)? Which is maybe just a viewpoint/documentation change.

## Philosophical answer: what are we restricting here and why?

It's not immediately clear to me _why_ it's considered a risk for
another application to be able to open connections through the same
Tor proxy as yours.  Naturally, you wouldn't want another app to use
the same circuits as yours, but you can mostly[^1] solve that by
setting your username/password to any hard-to-guess random values, and
having stream isolation code take care of that for you.

I guess that we might worry about side-channel attacks, where a
hostile application is sending traffic through the Tor proxy in order
to introduce a timing signal into your traffic?  But any application
with network access could do that, whether it has Tor access or not.

[^1]: Actually, wait.  There's a possible problem here when you're
making lots of onion service connections, since IIRC in C Tor onion
service circuits aren't affected by isolation.  But in Arti, they are.
So at least that problem will go away as Arti moves to the fore.

Good to know that C Tor's onion service circuits aren't affected by isolation - although we aren't using isolation at the moment so it doesn't have an immediate impact.

I don't honestly know what risk the auditors had in mind when they flagged the issue of controlling access to the SOCKS port. I'll follow up with them about that. But I think it's probably fair to say that being able to send traffic through the Tor client's guard connection might plausibly make traffic manipulation attacks easier than just being able to send traffic over the same network interface as the guard connection. Although I don't know if a handwavy "hmm this seems like an attack surface" is enough to justify a feature request. :)

## An answer you probably can't use: embedding Arti

Right now, you can embed Arti in any Rust app.  Some folks have
already started to write wrappers for Java and other languages.  With
our RPC protocol, we intend to support embedding Arti in any
application written in any language that can call C and link a
library.

So with this solution, there is no SOCKS port at all, and nobody can
use your Tor client but you.

I think we'll want to move to embedding Arti via Java bindings in future, but we may still want to expose a SOCKS port so that we can use HTTP libraries that expect to talk to a SOCKS port.

Is that expected to be a supported way of using Arti? For example, if we're talking to Arti via bindings rather than RPC on the control port, will it still be possible to open a SOCKS port and will we still have a session ID that we can use as a capability on the SOCKS port?

## An answer you probably can't use: OS-specific restrictions

Because somebody will mention it if I don't: you could probably cobble
something together using OS specific restrictions, like containers or
selinux.  Of course, this isn't really something you can ship in a
convenient cross-platform way AFAIK, so it probably isn't going to be
any portable application's first resort.

-----
Sorry for all the text!  But I do hope it's at least somewhat interesting.

best wishes,

It was very interesting! Thanks for all the ideas. Looks like we have some good options.

Cheers,
Michael

Attachment: OpenPGP_0x11044FD19FC527CC.asc
Description: OpenPGP public key

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

_______________________________________________
tor-dev mailing list
tor-dev@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev