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