Skip to content
Snippets Groups Projects
Closed The new control port handling in Tor Browser 13 breaks a Tails security feature
  • View options
  • The new control port handling in Tor Browser 13 breaks a Tails security feature

  • View options
  • Closed Issue created by anonym

    Tails has a filtering control port proxy called onion-grater. It is useful in Tails since it has a system-wide tor instance shared among many applications and users, and we want to be able to prevent information leaks (and other dangerous actions) over the control port between the tor clients.

    In particular, it has a feature where a client that both uses the control port and socks port and subscribes to STREAM events only get those that "belong" to itself. This feature was tailored to Tor Browser, so in case it is compromised it will not see other applications' stream usage. This feature also used to intercept getinfo circuit-status and only list the circuits that are attached to one of its streams. This worked fine for Tor Browser <= 12.5.

    With Tor Browser 13 things got complicated for filtering circuit information (filtering stream information is still doable just like before). The new implementation also subscribes to CIRC events and keeps track of circuits throughout their lives, and expects to have learned about a circuit being built before it sees that circuit referenced by some stream event, otherwise it throws an error and discards that event (which breaks the circuit view in Tor Browser). This makes sense, but onion-grater ends up with a "chicken and egg" problem: in general, when a circuit is built we don't know what it is going to be used for, we only know that for sure when a stream has been attached to it. So in order to know if a CIRC n BUILT event (which is what Tor Browser uses to start tracking it) should be forwarded or discarded we need a STREAM event from the future.

    This could be fixed in onion-grater by saving CIRC n BUILT events and injecting them before forwarding the STREAM event that establishes the circuit's ownership, but we already are concerned about onion-grater's complexity and do not want to do this.

    I believe this could be solved in Tor Browser if it didn't immediately throw an error when it receives a STREAM event that refers to an "unknown" circuit, but first tries a getinfo circuit-status and accepts the STREAM event if it learned about the circuit. This would make the implementation almost degenerate to the pre-13 polling, which is fine as far as Tails is concerned. But I say "almost" because there is a subtle issue here: pre-13 we would always poll so we would never have outdated info, but with 13 the info we have about circuits is kept and reused, and only invalidated once the corresponding CIRC n CLOSE event is received. So we would have to allow (and filter!) CIRC events too, but it would be pretty wonky:

    1. Tor Browser subscribes to both CIRC and STREAM events, filtered by onion-grater
    2. Let's say circuit n is built, so a CIRC n BUILT event is sent to Tor Borwser via onion-grater
    3. But onion-grater sees that Tor Browser doesn't "own" any stream that uses circuit n, so the CIRC n BUILT event is dropped, so it is "unknown" to Tor Browser
    4. Later Tor Browser opens a stream that is attached to circuit n
    5. onion-grater forwards the STREAM event for the stream using circuit n to Tor Browser
    6. Tor Browser notices that circuit n is "unknown", but it does what I proposed above and polls with getinfo circuit-status instead of discarding it
    7. onion-grater intercepts getinfo circuit-status and given what it learned in step 5 it knows that circuit n is owned by Tor Browser so it can be included in the response
    8. Tor Browser gets the response and now knows about circuit n so it accepts the STREAM event
    9. Eventually, after Tor Browser is done with the stream and tor decides to close circuit n, a CIRC n CLOSE is issued, onion-grater forwards it to Tor Browser, and it stops tracking circuit n

    I guess it works, but it feels pretty fragile and ugly. So I am not sure I want you to implement the fix above. What do you think? Perhaps you have some other, saner solution that I have missed?

    Linked items ... 0

  • Activity

    • All activity
    • Comments only
    • History only
    • Newest first
    • Oldest first
    Loading Loading Loading Loading Loading Loading Loading Loading Loading Loading