Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Tor dns leak #7769

Merged
merged 4 commits into from
Feb 4, 2021
Merged

Fix Tor dns leak #7769

merged 4 commits into from
Feb 4, 2021

Conversation

darkdh
Copy link
Member

@darkdh darkdh commented Feb 2, 2021

Resolves brave/brave-browser#13527

This PR

Disable CNAME adblock for Tor to prevent it from sending DoH or standard DNS query which will not be routed through Tor

1. Fixes DoH requests should respect proxy config, matching the behavior as Firefox, so that DoH requests will route through Tor
2. Enforce DoH for DNS queries sent by CNAME adblock because users can turn DoH off and we currently don't have a way to route insecure DNS lookup through Tor(proxy config). We can consider implementing Proxy DNS when using SOCKS v5(network.proxy.socks_remote_dns) that Firefox has so we don't have to enforce DoH for this
3. Skip CNAME adblock DNS lookup if DoH mode is not secure or DoH server list is empty

Submitter Checklist:

  • There is a ticket for my issue.
  • Used Github auto-closing keywords in the commit message.
  • Wrote a good PR/commit description
  • Added appropriate labels (QA/Yes or QA/No; release-notes/include or release-notes/exclude; OS/...) to the associated issue
  • Checked the PR locally: npm run test -- brave_browser_tests, npm run test -- brave_unit_tests, npm run lint, npm run gn_check, npm run tslint
  • Ran git rebase master (if needed).
  • Requested a security/privacy review as needed.

Reviewer Checklist:

  • New files have MPL-2.0 license header.
  • Adequate test coverage exists to prevent regressions
  • Major classes, functions and non-trivial code blocks are well-commented
  • Changes in component dependencies are properly reflected in gn
  • Code follows the style guide
  • Test plan is specified in PR before merging

After-merge Checklist:

Test Plan:

DoH off

  1. Follow the section Using the (Pre)-Master-Secret to setup SSLKEYLOGFILE
    https://wiki.wireshark.org/TLS
  2. After Wireshark is capturing traffic, use the dns filter
  3. Launch Brave
  4. Go to brave://settings/security and turn off Use secure DNS
  5. Open Tor window
  6. Navigate to https://tools.ietf.org/
  7. After site loaded, stop Wireshark capturing
  8. There shouldn't be any DNS query or DoH query for tools.ietf.org

DoH enabled

  1. Follow the section Using the (Pre)-Master-Secret to setup SSLKEYLOGFILE
    https://wiki.wireshark.org/TLS
  2. After Wireshark is capturing traffic, use the dns filter
  3. Launch Brave
  4. Go to brave://settings/security and make sure Use secure DNS is on and use custom Cloudflare resolver
  5. Open Tor window
  6. Navigate to https://tools.ietf.org/
  7. After site loaded, stop Wireshark capturing
  8. There shouldn't be any DNS query or DoH query for tools.ietf.org

@darkdh darkdh requested a review from a team as a code owner February 2, 2021 00:57
@darkdh darkdh self-assigned this Feb 2, 2021
@@ -148,13 +161,35 @@ class AdblockCnameResolveHostClient : public network::mojom::ResolveHostClient {
// See https://crbug.com/872665
optional_parameters->source = net::HostResolverSource::DNS;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ResolveHostParameters::secure_dns_mode_override for SECURE mode is useless without specifying doh_server.
So we have to do it through DnsConfigOverrides

Comment on lines 166 to 169
// Enforce DoH for Tor
// TODO(darkdh): we can consider implementing
// "Proxy DNS when using SOCKS v5" (network.proxy.socks_remote_dns)
// like Firefox has so that we don't have to enforce DoH
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a heads up about brave/brave-browser#13414 - we should be able to remove most of this machinery once we rebase onto CR89, so I'd recommend keeping the fixes here as minimal as possible!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like we should be setting this stuff when the Tor connection is created because presumably we need to always use it? Not just for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally, when we are in Tor window, we don't need to send ANY dns queries. We route all the HTTP/HTTPS traffic to tor proxy without knowing the IP, that means we just send hostname to proxy and the Tor exit node will do the resolving.

Copy link
Member

@diracdeltas diracdeltas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great but i don't think we should enable DoH for users who haven't picked a DoH provider, because IIUC they need to consent to the provider's terms of service. for users who haven't picked a DoH provider, can we just disable cname adblocking for them in Tor mode?

request_->SetExtraRequestHeaders(extra_request_headers);
// Disable secure DNS for any DoH server hostname lookups to avoid deadlock.
request_->SetDisableSecureDns(true);
- request_->SetLoadFlags(request_->load_flags() | LOAD_DISABLE_CACHE |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can avoid this patch by defining LOAD_BYPASS_PROXY as LOAD_DISABLE_CACHE. If that doesn't work for some reason you should use a define/chromium_src override after the original call instead of changing it to minimize the patch

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

auto request_info = std::make_shared<brave::BraveRequestInfo>(GURL());
int rc =
OnBeforeURLRequest_AdBlockTPPreWork(ResponseCallback(), request_info);
EXPECT_TRUE(request_info->new_url_spec.empty());
EXPECT_EQ(rc, net::OK);
}

TEST_F(BraveAdBlockTPNetworkDelegateHelperTest, ByassTor) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ByPassTor

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually I think this is a bad name because it makes it sound like it should be bypassing Tor and that's exactly the opposite of what we are doing. Maybe something like DisableInsecureRequestsOverTor

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

};
} // namespace

class BraveAdBlockTPNetworkDelegateHelperTest : public testing::Test {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this fixture is not related to existing tests, so you could leave them as is and give the test class more relevant name

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


#include "net/base/load_flags.h"

#define LOAD_BYPASS_PROXY LOAD_DISABLE_CACHE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't think we should do this for all requests. I checked git history around this code (https://chromium-review.googlesource.com/c/chromium/src/+/1843334/10/net/dns/dns_transaction.cc), and the authors say LOAD_BYPASS_PROXY is here to prevent deadlocks.

So we should either try upstreaming this or limit to tor-related requests

Copy link
Member Author

@darkdh darkdh Feb 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, I actually can't really imagine why we'd ever want to bypass the proxy for DoH requests. That seems like it would actually prevent requests from working at all if the proxy was required for access and non-proxy requests are blocked by firewall

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a discussion with upstream net dev
https://groups.google.com/u/1/a/chromium.org/g/net-dev/c/GI4E9ERwPgw

@diracdeltas diracdeltas self-requested a review February 3, 2021 18:55
@darkdh darkdh force-pushed the tor-dns-leak branch 2 times, most recently from dbb13b2 to 689261a Compare February 3, 2021 22:16
@darkdh
Copy link
Member Author

darkdh commented Feb 3, 2021

per discussion on slack with @bridiver and @iefremov, we came to a conclusion that disabling CNAME adblock for Tor would be best option now. Considering in order to make DoH route through Tor, we need to remove LOAD_BYPASS_PROXY for dns transaction but it might introduce dns and proxy code looping when we need to resolve proxy name. see (https://groups.google.com/u/1/a/chromium.org/g/net-dev/c/GI4E9ERwPgw)
So if we want to route DoH through Tor, we need fine grained solution for it and also need a bigger discussion about this with privacy and security

@fmarier
Copy link
Member

fmarier commented Feb 3, 2021

we came to a conclusion that disabling CNAME adblock for Tor would be best option now. Considering in order to make DoH route through Tor, we need to remove LOAD_BYPASS_PROXY for dns transaction but it might introduce dns and proxy code looping when we need to resolve proxy name.

Sounds like a good compromise to me.

@darkdh darkdh requested review from iefremov and bridiver February 4, 2021 02:53
// DoH or standard DNS quries won't be routed through Tor, so we need to skip
// it.
if (ctx->browser_context->IsTor()) {
return net::OK;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to disable adblocker in tor windows. What we need to do here is an adblocking pass without CNAME resolving, e.g. we can directly call ShouldBlockAdWithOptionalCname with empty CNAME

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Tested on Firefox: When DoH is enabled, the requests will route through
proxy
because we currently have no better way to route insecure DNS query
through proxy like "Proxy DNS when using SOCKS v5"
(network.proxy.socks_remote_dns) that Firefox has
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[hackerone] Tor DNS issue
6 participants