Safari with Prevent Cross-Site Tracking enabled bypasses NEDNSProxyProvider

Hi, I’ve encountered an issue with Safari’s behavior when Prevent Cross-Site Tracking is enabled in iOS, related to DNS filtering via an implemented NEDNSProxyProvider. Here’s a step-by-step breakdown:

  1. In Safari, when attempting to query a blocked domain (according to the filtering policy of the NEDNSProxyProvider), the page is blocked as expected.
  2. Closing Safari without closing the tab with the blocked domain.
  3. Reopening Safari – Expected result: The page remains blocked; Actual result: The page loads and bypasses the NEDNSProxyProvider (no logs are received for this flow).
  4. Tapping the refresh button causes the page to be blocked, as the DNS Proxy Provider intercepts the new request.

Note: This issue is only reproducible in general tabs in Safari. In private tabs, a fresh DNS query is generated each time, and the blocking behavior works as expected. I also tested Google Chrome, where the domain is blocked consistently.

I attempted to filter this issue via Content Filter, but the only connection received by NEFilterDataProvider is for com.apple.Safari.SearchHelper with ssl.gstatic.com.

Could you advise on how to handle this behaviour? Would be grateful to hear any ideas

Answered by AndriiSulimenko in 819507022

I found that the issue here is that iOS switches to another cache policy when there's no response from the DNS proxy

  • returnCacheDataElseLoad: Use existing cache data, regardless or age or expiration date, loading from originating source only if there is no cached data.

In normal cases it uses:

  • useProtocolCachePolicy: Use the caching logic defined in the protocol implementation, if any, for a particular URL load request.

For future reference, one of the ways to handle this is verify cache policy for intercepted browser flows within your Content Filter Providers. This way, you could add additional logic for flow filtering or remediation

Please use Feedback Assistant to post a bug report about this, then include the "FBnnnnnnnn" ID here.

Thank you! Filed a bug report: FB16148630

After some testing, it appears that the main issue is related to browser caching. When a connection was previously established, the browser uses its private cache to load the resource on subsequent launches, bypassing the NEDNSProxyProvider

Is there a way to handle this behaviour without explicitly blocking socket/browser flows in NEFilterDataProvider?

The app is deployed via MDM, so if a solution involves a configuration payload for supervised devices, that would be a suitable option as well. Thank you!

Accepted Answer

I found that the issue here is that iOS switches to another cache policy when there's no response from the DNS proxy

  • returnCacheDataElseLoad: Use existing cache data, regardless or age or expiration date, loading from originating source only if there is no cached data.

In normal cases it uses:

  • useProtocolCachePolicy: Use the caching logic defined in the protocol implementation, if any, for a particular URL load request.

For future reference, one of the ways to handle this is verify cache policy for intercepted browser flows within your Content Filter Providers. This way, you could add additional logic for flow filtering or remediation

Safari with Prevent Cross-Site Tracking enabled bypasses NEDNSProxyProvider
 
 
Q