pmarks-net/ipvfoo

Safari Extension

stefan1983 opened this issue · 15 comments

I would love to have ipvfoo as SAFARI Extension. Would be great if you could put this onto your roadmap.

Thanks

A1bi commented

I tried to port IPvFoo to Safari since it has recently introduced support for the WebExtensions API. Unfortunately the server IP address essential to IPvFoo is omitted from all web request event details. I can imagine that this is intended by Apple for whatever reason but I will open a bug report anyway.

I recently got macOS Ventura running in KVM, and tried to build IPvFoo for Safari:

% xcrun safari-web-extension-converter src

This is the resulting error:

  • An extension with a non-persistent background page cannot listen to webRequest events.
  • The service_worker script failed to load due to an error.

Screenshot 2023-09-17 at 5 42 23 PM

Using firefox-manifest.json with 'page_action' renamed to 'action', it gets far enough to render a ? and the popup, but chrome.webRequest is undefined.

Using the old manifestv2 branch, I'm able to log webRequest.onResponseStarted events, but the ip field is missing. So even when Safari adds support for webRequest in MV3, IPvFoo will be unimplementable unless they also start reporting IP addresses.

While writing this up, I noticed that A1bi already reached the same conclusion 2 years ago... at least I can report that nothing has changed since then.

Any news about it?

@pmarks-net, mudou de ideia sobre desenvolver para Safari essa semana extensão?

https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest#browser_compatibility > onResponseStarted > details.ip > Safari = No

If that ever changes, I can start working on this.

@pmarks-net

Hello, seem onResponseStarted > details.ip are now supported since Safari 18.4 (released on March 31).
Can you check it out whenever that function working correctly?

Thanks

A1bi commented

@Deafboy91 I just tested it and unfortunately it is still not supported. This chart reflects that.

Went down a rabbit hole and managed to get a fully functional Safari extension working, got the IP addresses by using some Swift magic (opening a TCP connection to the domain to see the IP the system resolved to)

Feel free to give it a try, should also work on iOS, just run make safari-run-macos https://github.com/agoodkind/ipvfoo

Image Image

I had to shuffle around some files and throw together a few build scripts to get things easy enough to work with

The makefile also includes targets for chrome and Firefox

@agoodkind, you win internet points for making that work, but native messaging to a stub that creates additional TCP connections doesn't meet IPvFoo's "without creating any additional network traffic" goal, so I don't expect to mainline that solution.

I once considered using the name IPv-ometer, which more accurately describes the technological terror you've constructed.

It technically doesn’t establish a full connection it kills it just after it gets the DNS resolution step,

https://github.com/agoodkind/ipvfoo/blob/master/safari/Shared%20(Extension)/DNSResolver.swift

case ready - The connection is established, and ready to send and receive data.

If I'm reading this correctly, it resolves DNS and performs a full TCP handshake, then closes the connection. No TLS or HTTP.

It technically doesn’t establish a full connection it kills it just after it gets the DNS resolution step,

https://github.com/agoodkind/ipvfoo/blob/master/safari/Shared%20(Extension)/DNSResolver.swift

case ready - The connection is established, and ready to send and receive data.

If I'm reading this correctly, it resolves DNS and performs a full TCP handshake, then closes the connection. No TLS or HTTP.

Fair point about violating the principle. I took a look again and ended up rewriting part of the resolver, so now it uses UDP instead of TCP. This means there's no TCP handshake (no SYN/SYN-ACK/ACK) and no TLS or HTTP connection established. The connection reaches "ready" state immediately after DNS resolution and gets cancelled before sending any data. So technically it's not creating "additional TCP connections" anymore - just triggering the system DNS resolver and extracting the result. https://github.com/agoodkind/ipvfoo/blob/669422972b89af14e6d53e7d4d0b17c936a3a14f/safari/Shared%20(Extension)/DNSResolver.swift#L39-L68

I also added caching and deduplication on the JavaScript side. When a page loads, multiple requests for the same domain arrive in parallel. Now the first request starts the DNS lookup, and subsequent requests wait for that same promise rather than triggering additional lookups. Completed lookups are cached for 10 seconds to avoid repeated requests when browsing the same site. https://github.com/agoodkind/ipvfoo/blob/669422972b89af14e6d53e7d4d0b17c936a3a14f/src/lib/safari.js#L113-L140