Determine outgoing flow source IPs without allowing data leakage using NEFilterDataProvider

I'm looking for help with a network extension filtering issue. Specifically, we have a subclass of NEFilterDataProvider that is used to filter flows based upon a set of rules, including source IP and destination IP. We've run into an issue where the source IP is frequently 0.0.0.0 (or the IPv6 equivalent) on outgoing flows. This has made it so rules based upon source IP don't work. This is also an issue as we report these connections, but we're lacking critical data. We were able to work around the issue somewhat by keeping a list of flows that we allow that we periodically check to see if the source IP is available, and then report after it becomes available.

We also considered doing a "peekBytes" to allow a bit of data to flow and then recheck the flow, but we don't want to allow data leakage on connections that should be blocked because of the source IP.

Is there a way to force the operating system or network extension frameworks to determine the source IP for an outbound flow without allowing any bytes to flow to the network?

STEPS TO REPRODUCE

  1. Create a network filtering extension for filtering flows using NEFilterDataProvider
  2. See that when handleNewFlow: is called, the outgoing flow lacks the source IP (is 0.0.0.0) in most cases

There is this post that is discussing a similar question, though for a slightly different reason. I imagine the answer to this and the other post will be related, at least as far as NEFilterDataProvider:handleNewFlow not having source IP is considered.

Thanks!

Written by traceguimont in 782600021
we don't want to allow data leakage on connections that should be blocked because of the source IP.

Hmmm. If you use the peek verdict then you get a chance to reject the flow before any bytes get transferred. Or are you worried that simply the act of connecting is a data leak?

If that’s the case then things get conceptually tricky. Apple platforms make extensive use of Happy Eyeballs, which makes it hard to filter on the source address without connecting.

Imagine a Mac on Wi-Fi and Ethernet, both of which lead to the Internet. When Safari connects to a server, the Network framework Happy Eyeballs implementation kicks in and starts two connections, one over each interface. Whichever one wins becomes the real connection, and the others are dropped. For more on this see Understanding Also-Ran Connections.

However, the overall connection is reported to your filter as a single flow. That flow can’t report a local endpoint until the connection has gone through, because each of the candidate connections has a different local endpoint. Once one connection has gone through, meaning that Happy Eyeballs now has a winner, the local endpoint is available but you’ve ‘leaked’ a connection.

What behaviour are you expecting from your content filter in a situation like this?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Determine outgoing flow source IPs without allowing data leakage using NEFilterDataProvider
 
 
Q