iPadOS 15 CFNetwork bypasses proxy after 403 response for nested requests

Since the release of iPadOS 15 we have noticed some apps as well as com.apple.webkit will bypass a proxy server for nested NSURLSession requests if the first request receives a 403 response.

Additionally the behaviour seems to be restricted to device configured with automatic proxy settings for a given network. If proxy settings are set to manual the behaviour doesn't occur.

Is this an issue with the new feature added to iPadOS 15:

URLSession now includes async functions. (68890254)

error  11:41:38.747890 +1000 Hello_World nw_http_connect_process_response http connect Proxy received status: HTTP/1.1 403 Forbidden



default  11:41:38.752065 +1000 Hello_World [C5.1.1 192.168.0.10:3128 failed resolver (satisfied (Path is satisfied), interface: en0, ipv4, dns, proxy)] event: resolver:children_failed @0.091s





info  11:41:38.752232 +1000 Hello_World nw_endpoint_handler_start [C5.1.2 Hostname#fc891996:443 initial path ((null))]





default  11:41:38.752582 +1000 Hello_World [C5.1.2 Hostname#fc891996:443 initial path ((null))] event: path:start @0.091s







default  11:41:38.753731 +1000 Hello_World [C5.1.2 Hostname#fc891996:443 waiting path (satisfied (Path is satisfied), interface: en0, ipv4, dns, proxy)] event: path:satisfied @0.092s, uuid: 35A79C08-A4E5-4EC9-A784-78C4F560AC42







default  11:41:38.754288 +1000 Hello_World [C5.1.2 Hostname#fc891996:443 in_progress resolver (satisfied (Path is satisfied), interface: en0, ipv4, dns, proxy)] event: resolver:start_dns @0.093s







info  11:41:38.754532 +1000 Hello_World nw_resolver_create_dns_getaddrinfo_locked [C5.1.2] Starting host resolution Hostname#fc891996:443, flags 0xc000d000 proto 0 using hostname: <redacted hostname>





info  11:41:38.757527 +1000 Hello_World nw_resolver_create_dns_getaddrinfo_locked_block_invoke [C5.1.2] Got 3 DNS results





info  11:41:38.757615 +1000 Hello_World nw_resolver_create_dns_getaddrinfo_locked_block_invoke [C5.1.2] Got DNS result type NoAddress ifindex=0 <private> <private> IN6ADDR_ANY





info  11:41:38.757702 +1000 Hello_World nw_resolver_create_dns_getaddrinfo_locked_block_invoke [C5.1.2] Got DNS result type ServiceBinding ifindex=0 <private> <private> <NULL>





info  11:41:38.757751 +1000 Hello_World nw_resolver_create_dns_getaddrinfo_locked_block_invoke [C5.1.2] Got DNS result type Add ifindex=0 <private> <private> IPv4#2535179d





info  11:41:38.757792 +1000 Hello_World nw_resolver_create_dns_getaddrinfo_locked_block_invoke [C5.1.2] Got DNS negative reason: query suppressed





info  11:41:38.757837 +1000 Hello_World nw_resolver_create_dns_getaddrinfo_locked_block_invoke [C5.1.2] SVCB queries are complete





default  11:41:38.758300 +1000 Hello_World nw_endpoint_resolver_update [C5.1.2 Hostname#fc891996:443 in_progress resolver (satisfied (Path is satisfied), interface: en0, ipv4, dns, proxy)] Adding endpoint handler for IPv4#2535179d:443





default  11:41:38.758851 +1000 Hello_World [C5.1.2 Hostname#fc891996:443 in_progress resolver (satisfied (Path is satisfied), interface: en0, ipv4, dns, proxy)] event: resolver:receive_dns @0.098s





info  11:41:38.758905 +1000 Hello_World nw_resolver_create_dns_getaddrinfo_locked_block_invoke [C5.1.2] Invalidating getaddrinfo DNS object







info  11:41:38.759032 +1000 Hello_World nw_endpoint_resolver_start_next_child [C5.1.2 Hostname#fc891996:443 in_progress resolver (satisfied (Path is satisfied), interface: en0, ipv4, dns, proxy)] starting child endpoint IPv4#2535179d:443





info  11:41:38.759130 +1000 Hello_World nw_endpoint_handler_start [C5.1.2.1 IPv4#2535179d:443 initial path ((null))]





default  11:41:38.759490 +1000 Hello_World [C5.1.2.1 IPv4#2535179d:443 initial path ((null))] event: path:start @0.098s





default  11:41:38.760370 +1000 Hello_World [C5.1.2.1 IPv4#2535179d:443 waiting path (satisfied (Path is satisfied), interface: en0, ipv4, dns, proxy)] event: path:satisfied @0.099s, uuid: 13B361F5-6CC9-4A72-AEB8-35655515FBBB

URLSession now includes async functions. (68890254) error 11:41:38.747890 +1000 Hello_World nw_http_connect_process_response http connect Proxy received status: HTTP/1.1 403 Forbidden

You may want to check how your proxy is setup against this deprecation item in the release notes.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

I've tested the behaviour against http and https delivered PAC files and the behaviour is the produced in both cases. Additionally if a 403 response is not returned for the primary request in question then the nested requests don't appear to bypass proxy.

I have come across a way to force the nested functions to use proxy. I suspected that the network handler for the nested functions is incorrectly interpreting a 403 forbidden response from the proxy as the PAC file being unreachable. By setting "ProxyPACFallbackAllowed" to False has prevented the nested requests from failing to use the proxy_resolver.

Whilst we can set this in a profile for some managed wifi networks users that connect to networks without a profile will not have control over this setting.

iPadOS 15 CFNetwork bypasses proxy after 403 response for nested requests
 
 
Q