Content Filter Network Extension not intercepting localhost (127.0.0.1) connections

Hi, I am not able to see the localhost(127.0.0.1) connection request capture by the content filter network extension but all other connection is being intercepted by the NE. Is there any specific way to add in filter setting even after using following filter setting.

override func startFilter(completionHandler: @escaping (Error?) -> Void) {
    let filterRules = ["0.0.0.0", "::"].map { address -> NEFilterRule in
      let bothNetworkRule = NENetworkRule(remoteNetwork: nil,
                         remotePrefix: 0,
                         localNetwork: nil,
                         localPrefix: 0,
                         protocol: .any,
                         direction: .any )
      return NEFilterRule(networkRule: bothNetworkRule, action: .filterData)
    }

    let filterSettings = NEFilterSettings(rules: filterRules, defaultAction: .allow)

    apply(filterSettings) { error in
       if let applyError = error {
        os_log("Failed to apply filter settings: %@", applyError.localizedDescription)
       }
       completionHandler(error)
    }
Right. Taking a look at the NENetworkRule API I see:

Code Block text
@method initWithRemoteNetwork:prefix:localNetwork:prefix:interface:protocol:direction:
@discussion Initialize a newly-allocated NENetworkRule object that matches traffic by remote network, local network, protocol, and direction. If both remoteNetwork and localNetwork are nil then the rule will match all traffic of the given protocol and direction, except for loopback traffic. To match loopback traffic create a NENetworkRule with remoteNetwork and/or localNetwork properties that explicitly match traffic to the loopback address (127.0.0.1 or ::1).
@param remoteNetwork An endpoint object that contains the remote port and the remote address or network that the rule matches. This endpoint must contain an address, not a hostname.
If the address is a wildcard address (0.0.0.0 or ::) then the rule will match all destinations except for loopback (127.0.0.1 or ::1). To match loopback traffic set the address to the loopback address.
If the address is a wildcard address (0.0.0.0 or ::) then the rule will match all local networks except for loopback (127.0.0.1 or ::1). To match loopback traffic set the address to the loopback address.


Code Block objective-c
@interface NENetworkRule : NSObject <NSSecureCoding,NSCopying>
- (instancetype)initWithRemoteNetwork:(nullable NWHostEndpoint *)remoteNetwork
remotePrefix:(NSUInteger)remotePrefix
localNetwork:(nullable NWHostEndpoint *)localNetwork
localPrefix:(NSUInteger)localPrefix
protocol:(NENetworkRuleProtocol)protocol
direction:(NETrafficDirection)direction API_AVAILABLE(macos(10.15)) API_UNAVAILABLE(ios, tvos) __WATCHOS_PROHIBITED;
@end


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Hi Matt,

Along with old rule I tried to add the new NENetworkRule rules matching any port on localhost (127.0.0.1 ) but still didn't see handleNewFlow() called for localhost connection requests. Following is the rule written
let loNetworkRules1 = NENetworkRule(
      remoteNetwork: nil,
      remotePrefix: 0,
      localNetwork: NWHostEndpoint(hostname: "127.0.0.1", port: "0"),
      localPrefix: 0,
      protocol: .any,
      direction: .any
    )
    let loFilterRule1 = NEFilterRule(networkRule: loNetworkRules1, action: .filterData)
     
    let loNetworkRules2 = NENetworkRule(
      remoteNetwork: NWHostEndpoint(hostname: "127.0.0.1", port: "0"),
      remotePrefix: 0,
      localNetwork: nil,
      localPrefix: 0,
      protocol: .any,
      direction: .any
    )
    let loFilterRule2 = NEFilterRule(networkRule: loNetworkRules2, action: .filterData)
     
    let loFilterSettings = NEFilterSettings(rules: [loFilterRule1,loFilterRule2], defaultAction: .allow)
     
     apply(loFilterSettings) { error in
       if let applyError = error {
         netopsLog(level: LOGLEVEL_ERROR, format: "Failed to apply localhost filter settings: %@", applyError.localizedDescription)
       }
       completionHandler(error)
     }
Interesting. Taking a look at this from the documentation:

To match loopback traffic create a NENetworkRule with remoteNetwork and/or localNetwork properties that explicitly match traffic to the loopback address (127.0.0.1 or ::1).

I created a rule that looked like:

Code Block objective-c
NWHostEndpoint *hostEndpoint = [NWHostEndpoint endpointWithHostname:@"127.0.0.1" port: @"0"];
NENetworkRule *localHostRule = [[NENetworkRule alloc] initWithRemoteNetwork: hostEndpoint
remotePrefix: 0
localNetwork: hostEndpoint
localPrefix: 0
protocol: NENetworkRuleProtocolAny
direction: NETrafficDirectionAny];
NEFilterRule *anyLocalHostRule = [[NEFilterRule alloc] initWithNetworkRule: localHostRule action: NEFilterActionFilterData];
NEFilterSettings *filterSettings = [[NEFilterSettings alloc] initWithRules:@[anyLocalHostRule] defaultAction: NEFilterActionAllow];


And matched a local curl request on my machine:

Code Block text
2020-12-09 07:20:19.855446-0800 0x36c0bb ## FilterDataProvider ## handleAppMessage with flow with direction: (Outbound) and
identifier = ...
sourceAppIdentifier = .com.apple.curl
sourceAppVersion =
sourceAppUniqueIdentifier = 20:{length = 20, bytes = ***}
procPID = 66376
eprocPID = 66376
direction = outbound
inBytes = 0
outBytes = 0
signature = 32:{length = 32, bytes = *** ... d33a0f32 33e9af35 }
socketID = 1f9eef3f922ee2
localEndpoint = 0.0.0.0:0
remoteEndpoint = 127.0.0.1:8080
protocol = 6
family = 2
type = 1
procUUID = ...
eprocUUID = ... with url: (null)
2020-12-09 07:20:19.855496-0800 0x36c0bb (socketFlow):
identifier = ...
sourceAppIdentifier = .com.apple.curl
sourceAppVersion =
sourceAppUniqueIdentifier = 20:{length = 20, bytes = ***}
procPID = 66376
eprocPID = 66376
direction = outbound
inBytes = 0
outBytes = 0
signature = 32:{length = 32, bytes = *** ... d33a0f32 33e9af35 }
socketID = 1f9eef3f922ee2
localEndpoint = 0.0.0.0:0
remoteEndpoint = 127.0.0.1:8080
protocol = 6
family = 2
type = 1
procUUID = ...
eprocUUID = ... and remoteEndpoint: 127.0.0.1:8080


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Content Filter Network Extension not intercepting localhost (127.0.0.1) connections
 
 
Q