Restrict interaction with local network

Hello all,
I noticed that Brave does not restrict the interaction of external websites with the local network. In my opinion, this poses an unnecessary privacy risk, as it can be abused to scan for ports or identify running services, network topology, etc. I see no legitimate use case that justifies this behaviour (please correct me if I am wrong on this point). It also poses a security risk when having vulnerable software running locally.

I know there are already countermeasures in place (blocked ports, throttling), which dont seem to fight the root problem.

I would really appreciate your thoughts on this!

Thank you very much.

Could you share some links to know what exactly is this? First time heard about it.

Some links:

https://xsleaks.dev/
https://noscript.net/abe/

I know there are a lot of tools that already prevent this behaviour. Still I am wondering why Brave does not come with this feature by default?

We do actually have filters in place to block these requests:

Did you actually noticing local connections being made on websites despite this protection?

2 Likes

Uhh, that explains why I wasnt able to receive a connection via:

Still I am able to get it working via

but there are many ways.

To answer your question, I was not able to observe any connection attempts that bypass this blacklist. Still I would be surprised if it wasn’t already being used in the wild.

I dont know the inner workings of brave, but is a blacklist really the only approach possible to prevent this?

Thanks!

That’s a good point, our list-based approach is incomplete. I have reopened our original issue:

I found four bypasses in total:

If you find any other ones, either let us know on GitHub or here.

I have also found the following (no guarantee of completeness):

  • the entire 127.0.0.0/8 address block (that is 16,777,214 addresses - maybe “127.” could be blocked for this purpose, but then again one needs to consider various encodings)
  • encodings: hex, octal, decimal, 0177.0.0.2, 127.2, 000000000000000000, [0:0:0:0:0:ffff:127.0.0.1], 0x7f.0.1.1, …
  • (finally, other private addresses such as 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 and router domains such as fritz.box)

I thought it might be useful to convert the ip address to a long first, then check the prefix of this one?

You’re right to point out that the whole /8 is reserved for the loopback address, but on my machine, only 127.0.0.1 gets routed back to my machine. It doesn’t look like using other addresses in this range would be a reliable way to portscan a user’s machine. Have you seen evidence of other addresses being commonly exposed by default on other operating systems for example?

I did include these encodings on my test page but I found that Chrome normalizes them to the usual notation before passing them to the adblock layer and so we don’t need to worry about them, they all get blocked by 127.0.0.1 for example.

That’s indeed something we should address, but it’s slightly different and actually the topic of ongoing work in Chromium:
https://wicg.github.io/private-network-access/

1 Like

I have tested it on my 20.04.2 Ubuntu and Arch, where the complete range is routed. I am able to receive a connection via 127.0.0.2 etc.

Thanks for the update, I will check it out!

You’re right. I looked a bit more into this and I found that:

  • the whole /8 is routed to the loopback interface
  • but not all services are listening on the whole /8

For example, on my machine, if I nmap 127.0.0.1, I get:

PORT     STATE SERVICE   VERSION
22/tcp   open  ssh       OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
25/tcp   open  smtp      Postfix smtpd

whereas if I nmap 127.0.1.25, I get only:

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)

So it’s probably not a reliable way to portscan a local machine (you would miss the services bound to 127.0.0.1), but it does leak some information about the services that listen on all interfaces.

I’ll file a separate issue for this since the way we fixed it for the other addresses isn’t going to work here:

Thanks for the new issue - I guess I can close this ticket here and switch to Github!