PLATFORM AND VERSION
iOS
Development environment: Xcode 16.0, macOS 15.0.1
Run-time configuration: iOS 17.5.1
DESCRIPTION OF PROBLEM
We are working on an iOS application that utilizes the NEFilterDataProvider class from the Network Extension framework to control network flows. However, we are encountering an issue where network flows are not being detected as expected.
Here are the details of our setup:
We are using the NEFilterDataProvider class to filter network traffic in our app.
The filtering setup works well for certain flows/apps, but we cannot detect Facebook network flows as intended.
The app is correctly configured with the necessary entitlements, and we have set up the required App Groups and Network Extension capabilities.
We would like to request guidance on how to troubleshoot or resolve this issue. Could you provide insights on:
Whether there are any known limitations or conditions under which network flows may not be detected by NEFilterDataProvider.
Recommendations for additional debugging techniques to better understand why some flows might not be captured.
Recommendations for additional code to be added to detect some flows that might not be captured.
Any specific scenarios or configurations that might be causing this issue in iOS.
STEPS TO CHECK
Replace below code in FilterDataProvider.
Try running the app and set debugger in FilterDataProvider.
Launch Facebook app.
You will observe that no NEFilterFlow is detected in handleNewFlow for actions such as posts, reels, etc.
import NetworkExtension
class FilterDataProvider: NEFilterDataProvider {
let blockedDomains = [
"facebook.com"
]
override func startFilter(completionHandler: @escaping (Error?) -> Void) {
// Perform any necessary setup here.
DNSLogger.shared.log(message: "Filter started")
completionHandler(nil)
}
override func stopFilter(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
// Perform any necessary cleanup here.
DNSLogger.shared.log(message: "Filter stopped with reason: \(reason)")
completionHandler()
}
override func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict {
var url: URL?
if let urlFlow = flow as? NEFilterBrowserFlow {
url = urlFlow.url
}
else {
let urlFlow = flow as? NEFilterSocketFlow
url = urlFlow?.url
}
guard let hostName = url?.host else { return .allow() }
DNSLogger.shared.log(message: "Domain reveived: \(hostName)")
return .allow()
}
// Handle inbound data (data received from the network)
override func handleInboundData(from flow: NEFilterFlow, readBytesStartOffset offset: Int, readBytes: Data) -> NEFilterDataVerdict {
DNSLogger.shared.log(message: "Inbound data: \(readBytes)")
return .needRules()
}
// Handle outbound data (data sent to the network)
override func handleOutboundData(from flow: NEFilterFlow, readBytesStartOffset offset: Int, readBytes: Data) -> NEFilterDataVerdict {
// Inspect or modify outbound data if needed
// For example, you could log the data or modify it before sending
DNSLogger.shared.log(message: "Outbound data: \(readBytes)")
return .needRules()
}
override func handleRemediation(for flow: NEFilterFlow) -> NEFilterRemediationVerdict {
return .needRules()
}
override func handleRulesChanged() {
// Handle any changes to the rules
}
}
1
4
432