Skip to content

Various SOCKS proxy leaks #493

@shihiro09

Description

@shihiro09

A few leaks I have noticed:

  1. UDP trackers are still enabled when --socks-url is passed. There is no way to disable them without stripping them from magnet links and falling back to a trackers file filled with HTTP trackers only.
  2. rqbit leaks the DNS resolution for HTTP trackers. This is because reqwest does local DNS resolution for socks5://. For proxied resolution, you must pass socks5h:// or socks4a://. Unfortunately, rqbit errors if passed a socks5h URI.
  3. Likewise, rqbit (via reqwest) is leaking DNS resolution for downloaded torrent files and peer blocklists (for the same reason as the above issue).
  4. This one is low severity, but reqwest currently has an experimental HTTP3 connector. After a quick audit of the reqwest code, it looks like there's no accounting for the proxy if HTTP3 is used (I could be wrong). In theory, an HTTPS tracker could be serving HTTP3 traffic (i.e. UDP traffic) which would not be proxied with reqwest in its current state. I'm not a very good rust developer so I don't know if http3 is enabled in rqbit's build of reqwest.
  5. Minor: The DHT is still active when --socks-url is passed, but this is not as big of an issue as it can be disabled.

I'm not sure if the UDP tracker one was an intentional tradeoff: i.e. there aren't very many HTTP trackers present in magnet links. But if a user passes a proxy to an application, it's generally expected that all traffic will be tunneled through the proxy, even if it degrades usability (for example, firefox auto-disables HTTP3 and various WebRTC functionality if a SOCKS proxy is active).

Solutions:

  1. Ignore UDP trackers if there is an active proxy (or perhaps add a flag --disable-udp-trackers).
  2. Allow socks5h and socks4a for socks_url (or maybe even require them, lest users make a mistake).
  3. Same as above.
  4. Ensure reqwest is built without HTTP3 support. Never attempt to use HTTP3 on an HTTPS tracker.
  5. Consider auto-disabling the DHT if a proxy is passed.

Temporary solutions (for anyone reading):

  1. Strip all magnet links of all trackers. Fall back to a tracker file with HTTP trackers only.
  2. Pre-resolve all domains in the trackers file to IP addresses (this may break things depending on the tracker -- the tracker might need a correct Host header for reverse proxying). Alternatively, write an LD_PRELOAD which returns no records for GAI (see below, this causes reqwest to silently pass the hostname to the proxy).
  3. LD_PRELOAD is the only solution for this one.
  4. Restricting oneself to HTTP trackers only (as opposed to HTTPS) is enough of a defense here.
  5. Pass --disable-dht.

This LD_PRELOAD will cause reqwest to pass the real hostname to the proxy:

int getaddrinfo(const char *name, const char *service,
                const struct addrinfo *hints, struct addrinfo **res) {
  if (res != NULL)
    *res = NULL;
  return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions