Closed Bug 1827173 Opened 2 years ago Closed 2 years ago

Fetch API allows timing-based port scanning

Categories

(Core :: DOM: Networking, defect, P2)

Firefox 112
defect

Tracking

()

RESOLVED WONTFIX

People

(Reporter: kiding, Unassigned)

References

(Depends on 1 open bug, )

Details

(Keywords: sec-want)

Attachments

(1 file)

(deleted), application/zip
Details
Attached file TO_POC.zip (deleted) —

Steps to reproduce:

Summary

While some mitigations against JavaScript-based port scanning have been applied to HTMLElement and WebSocket, the same does not seem to be true for WebAssembly. Using Go's net/http package, it is possible to create a practical timing-based port scanner.

How the Proof-of-Concept code works is as follows.

On macOS: Firstly, it requests to http://localhost:2 10000 times and measure the times between a request and a response to get a baseline "control" timing when a port is closed. Secondly, it requests to https://localhost with selected ports, each 200 times and measure the timings. Thirdly, if the average for a measurement exceeds 30% of the "control," remember the port as a candidate. Finally, perform the measurements again for candidates with different parameters to refine the result: measuring 1000 times, exceeding 70%.

On Windows: It simply requests to http://localhost with selected ports, each 10 times. If the measurement is faster than 80% of timeout (250ms, ) it’s considered open.

Proof-of-Concept demo videos (Tested on MacBook Air w/ M1, DELL XPS 13 Plus w/ i7-1260P)

The same problem is also present on Safari and Chrome. Separate reports have been filed.

Steps to reproduce

  1. Unzip the attachment: TO_POC.zip
  2. Open a web server in the folder: npx http-server -c-1
  3. Visit the web page: http://localhost:8080

Actual results:

JavaScript is able to locate opened ports.

Expected results:

JavaScript should not be able to locate opened ports.

Group: firefox-core-security → javascript-core-security
Component: Untriaged → JavaScript: WebAssembly
Product: Firefox → Core

This doesn't need to be hidden since it's a published technique (e.g. https://infosecwriteups.com/identify-website-users-by-client-port-scanning-using-webassembly-and-go-e9798b4aa05c) and discussed in several places.

Ultimately this isn't a "Web Assembly" problem but the fact that web pages can connect to localhost. If you can connect, you can use various features to detect different timings. The Private Network Access specification proposal would be one way to address this, but it will also break a lot of localhost-based services since it requires "opt-in".

Group: javascript-core-security
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: sec-want

Just to add notes about POC: the Go code is using http.NewRequest("GET", target, nil) which calls JS/DOM fetch() method (via Wasm imports).

The WebAssembly runtime in the Firefox does not provide any API to access the sockets or WebSockets directly. Such functionality is done via JS, which calls e.g. DOM fetch() method. The OP's POC can be reduced to use only fetch() that is called/measured from JavaScript directly, without Go and WebAssembly.

That makes sense. Perhaps DOM:Networking is a better component then.

Component: JavaScript: WebAssembly → DOM: Networking

The OP's POC can be reduced to use only fetch() that is called/measured from JavaScript directly, without Go and WebAssembly.

Looks like this is absolutely true for Firefox. I must have mistaken somewhere in the process. Firefox behaves the same way whether or not fetch() is called from JS or WASM. I apologize for the confusion.

Now this bug becomes "Fetch API allows timing-based port scanning," which might as well be invalid. If so, please do resolve it as invalid.

Summary: WebAssembly allows timing-based port scanning → Fetch API allows timing-based port scanning

As Daniel mentioned, this is a general problem that web pages can connect to local host. We might need to devise a general solution as the problem might be applicable for other WebAPI's as well.

Valentin, do you know if we have any solution in our plans ( for e.g. Private Network Access) which might mitigate these vulnerabilities?

Flags: needinfo?(valentin.gosu)

Yes, it seems we ought to start looking at local-network-access to mitigate this class of attacks.

Severity: -- → S3
Flags: needinfo?(valentin.gosu)
Priority: -- → P2

Thanks Valentin for your inputs.
kiding, I propose to close this bug report as WONTFIX as there are already general approaches planned to fix this.

Flags: needinfo?(kiding)

I understand. Thank you everyone!

Status: NEW → RESOLVED
Closed: 2 years ago
Flags: needinfo?(kiding)
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: