ipfs / ipfs-companion

Browser extension that simplifies access to IPFS resources on the web
https://docs.ipfs.tech/install/ipfs-companion/
Creative Commons Zero v1.0 Universal
2.07k stars 324 forks source link

DNS leak when browser is set to use DoH or a proxy #900

Open Snawoot opened 4 years ago

Snawoot commented 4 years ago

I've tried to reach authors via email provided in security policy for such reports, but I haven't received any response after two attempts. First attempts was made on 12 of June.

Description

Once enabled, IPFS Companion browser extension leaks some domain name requests via requests to local IPFS gateway on DNS resolve endpoint.

It violates user privacy in cases when direct DNS requests are unacceptable. Namely:

In fact, it breaks user's anonymity and confidentiality of some requests.

It's likely that such behavior violates Add-on Policies defined for Firefox extensions (see "compromises user privacy" in "Unexpected Behavior") and Google Chrome Web Store Developer Agreement (4.3 - privacy statement and 4.4.1.3 - interference with other network services and browser extensions).

To Reproduce

Steps to reproduce the behavior:

  1. Install IPFS Companion on any supported browser.
  2. Set browser to use SOCKS5 proxy with remote resolve or HTTP proxy or HTTPS proxy or DoH.
  3. Do a test on https://browserleaks.com/ip
  4. Observe DNS leaks in test results or in query log of DNS forwarder in your local net.

Expected behavior

No DNS leaks.

Screenshots

Dump of requests to local IPFS gateway from browser extensions:

pcap

Excerpt from query log of DNS forwarder on local network:

log

Desktop:

Additional context

PCAP file:

ipfs-companion.pcap.gz

Excerpt from query log of DNS forwarder on local network:

query.log

jessicaschilling commented 4 years ago

@Snawoot Thank you for filing this - confirming that it’s been received and seen.

lidel commented 4 years ago

Thank you @Snawoot for the very thorough and clear report. Below is my quick analysis of situation and potential next steps.

Clarification: go-ipfs leaks, not Companion

When go-ipfs opens /ipns/example.com it does DNSLink lookup internally, so even if Companion did not call /api/v0/dns at go-ipfs, the leak would still happen.

Just to be very clear, the "DNS leak" happens when:

It is a problem for mentioned setups, but for regular user with a browser that uses DNS resolver provided by the operating system there is no decrease of privacy (browser already does DNS leak for every visited website anyway).

That being said, browser vendors start to experiment with enabling DoH, and when that is enabled, we would indeed decrease privacy for default setups, which is a significant concern.

Why /api/v0/dns is called?

IPFS Companion checks if DNSLink exists to display IPFS integrations. Sadly there is no WebExtension API that would enable our extension to do DNS TXT record lookups using DoH configured in the browser. That is why we use /api/v0/dns in go-ipfs (assuming that user trusts their own DNS resolver).

Upstream issue for Firefox exists, but it is highly unlikely that we will see something like that any time soon in both Chromium and Firefox.

Mitigation

I see two ways to close the leak without changing anything in IPFS Companion or go-ipfs:

(M1) Disable DNSLink lookup when using DoH or proxy

Quick mitigation for those use cases is to disable DNSLink lookups in Preferences:

disbling-dnslink-2020-06-20--19-01-45

(M2) Run local caching server that forwards queries over TLS

Alternative is to run local DNS caching server configured to uses TLS. Example of relevant config for unbound:

forward-zone:
        name: "."
        forward-tls-upstream: yes
        # Cloudflare DNS
        forward-addr: 2606:4700:4700::1111@853#cloudflare-dns.com
        forward-addr: 1.1.1.1@853#cloudflare-dns.com
        forward-addr: 2606:4700:4700::1001@853#cloudflare-dns.com
        forward-addr: 1.0.0.1@853#cloudflare-dns.com
        # Quad9
        forward-addr: 2620:fe::fe@853#dns.quad9.net
        forward-addr: 9.9.9.9@853#dns.quad9.net
        forward-addr: 2620:fe::9@853#dns.quad9.net
        forward-addr: 149.112.112.112@853#dns.quad9.net

Potential ways of fixing underlying problem

(S1) Configurable DNS in go-ipfs

Configurable DNS and DoH support in go-ipfs is tracked in: https://github.com/ipfs/go-ipfs/issues/6532 If we used DoH for DNSLink lookup in go-ipfs by default, and made it possible for user to change DoH server, it should be enough. Both internal provessing and /api/v0/dns would use DoH, and there would be no leaking.

(S2) Configurable DNS in ipfs-companion

Implement DoH in IPFS Companion. Use a trusted DoH server for all DNSLink lookups and make it possible to configure DoH server in Companion Preferences screen.

Useful notes on binary format in DoH can be found in https://github.com/ipfs/helia-ipns/issues/53, but I am not sure if going this route makes sense. Even if Companion uses DoH and does not leak anything, when request for /ipns/example.com is redirected to localhost gateway go-ipfs will do the DNSLink lookup itself, defeating the leak protection in Companion.

This means we need S1, as it makes both internal and external lookups to go over DoH.

Summary

I believe S1 is the only viable fix I see atm, so this is blocked by upstream https://github.com/ipfs/go-ipfs/issues/6532

For now, we will update Companion's Privacy Policy and add a section that explicitly documents privacy considerations related to DNSLink support: https://github.com/ipfs-shipyard/ipfs-companion/pull/901


Let me know if I missed anything, or if you see a better way of tackling this that was not considered above in S1/S2 – feedback would be really appreciated.

Snawoot commented 4 years ago

I agree S1 is preferable. Apart from S2 downsides, there are additional reasons why it's better to have some sort of secure DNS precisely in go-ipfs:

RubenKelevra commented 3 years ago

Snawoot wrote:

[...] there are additional reasons why it's better to have some sort of secure DNS precisely in go-ipfs:

  • No protocol limitation. You may use plain DNS, DoT, DoH and DNSCrypt. Here is example of such software in Go with multi-protocol upstream DNS support. Amount of code responsible for interaction with all sort of upstreams is not too big: about 1.5k LOC with tests.
  • Finer control over implementation. There are no concurrency limits, no browser limits etc.
  • go-ipfs itself may have some benefit from incorporating secure DNS client. It may be useful in cases when bootstrap servers censored via DNS filtering and/or if you want to push fresh bootstrap nodes via floating DNS name.

Sorry for the off-topic.

Correct me when I'm wrong, but:

We also need a secure DNS to have a trusted anchor to mitigate any MITM-Attacks. Since signature verification on DNS queries is basically still in its infancy and only very few domain providers actually support DNSSEC anyway.

If we use plain text DNS requests and don't do any signature verification OR the domain has no DNSSEC information stored, we don't have any security for the content similar to a page that gets loaded over HTTP.

It would be nice if we could do at least secure DNS requests for any DNSLink request until DNSSEC validation is more feasible.

I added a ticket for DNSSEC validations of DNSLinks: https://github.com/ipfs-shipyard/ipfs-companion/issues/970

SgtPooki commented 1 year ago

grooming meeting notes: @SgtPooki to look at this and ensure labels/priority/etc are accurate.