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

Michael Rogers michael at briarproject.org
Thu Sep 12 09:20:48 UTC 2024


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 at briarproject.org> 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0x11044FD19FC527CC.asc
Type: application/pgp-keys
Size: 13413 bytes
Desc: OpenPGP public key
URL: <http://lists.torproject.org/pipermail/tor-dev/attachments/20240912/2d82b1c9/attachment-0001.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 495 bytes
Desc: OpenPGP digital signature
URL: <http://lists.torproject.org/pipermail/tor-dev/attachments/20240912/2d82b1c9/attachment-0001.sig>


More information about the tor-dev mailing list