Recording a Packet Trace

I want to track down which part of an app contacts a given domain listed in its App Privacy Report.

Following the instructions given here I am able to capture a packet trace, but traffic to the domain in question is encrypted using QUIC.

Is there a way to insert e.g. mitmproxy into the capture process in order to get hold of the SSLKEYLOGFILE so that I can decrypt the traffic?

Answered by DTS Engineer in 879819022

I was able to get this working today:

  1. On my Mac, running macOS 26.2, I downloaded the Mac version (mitmproxy-12.2.1-macos-arm64.tar.gz).

  2. I unpacked it.

  3. I moved it to the Applications folder.

  4. And launched it (which opens a Terminal window).

  5. It creates its CA (certificate authority) certificates in ~/.mitmproxy . I check that was all present:

    % ls -l ~/.mitmproxy 
    total 48
    -rw-r--r--@ 1 quinn  staff  1172 13 Mar 12:05 mitmproxy-ca-cert.cer
    -rw-r--r--@ 1 quinn  staff  1035 13 Mar 12:05 mitmproxy-ca-cert.p12
    -rw-r--r--@ 1 quinn  staff  1172 13 Mar 12:05 mitmproxy-ca-cert.pem
    -rw-------@ 1 quinn  staff  2384 13 Mar 12:05 mitmproxy-ca.p12
    -rw-------@ 1 quinn  staff  2847 13 Mar 12:05 mitmproxy-ca.pem
    -rw-r--r--@ 1 quinn  staff   770 13 Mar 12:05 mitmproxy-dhparam.pem
    
  6. On a victim device running 26.2…

    IMPORTANT This process involves changing system-wide trust settings. Given that, it’s not appropriate for a device you actually care about.

  7. I launched Safari and open a private browsing tab (this helps with subsequent steps).

  8. In Settings > Wi-Fi > My Network > Configure Proxy, I selected Manual, and entered my Mac’s IP address and port 8080.

  9. Back in Safari, I went to http://mitm.it.

  10. I tapped iOS > Get “mitmproxy-ca-cert.pem” and agreed to the download.

  11. In Settings > General > VPN & Device Management > mitmproxy, I ran through the install sequence.

  12. In Settings > About > Certificate Trust Settings, I enabled the “mitmproxy” CA.

  13. Back in Safari, I created a new tab and entered https://mitmproxy.org.

  14. In Terminal on my Mac, I saw those requests being proxied.

    Note If you press z, you can clear the list of requests which makes it easier to see the new ones.

  15. Back in Safari, I hit the refresh button and watched the requests continue to be proxied.

Neat-o!


I hit one really weird gotcha during this exercise. In step 13 I originally tested with https://example.com. That failed with a 502 Bad Gateway error. I suspect this is some special case within mitmproxy, because it only seems to affect that site.

Share and Enjoy

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

What platform are you on?

Oh, and are you using QUIC via HTTP/3? Or explicitly?

Share and Enjoy

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

What platform are you on?

iOS unfortunately

Oh, and are you using QUIC via HTTP/3? Or explicitly?

I'm not sure; let me check

It seems to be QUIC explicitly. And it's not us using it but some dependency we include - and yes, I am aware of https://developer.apple.com/documentation/Xcode/verifying-the-origin-of-your-xcframeworks :)

I also have been perusing the logs, but to no avail (Bundle Name and ID redacted):

default	2026-03-06 08:10:29.582324 +0100	mDNSResponder	dnssd_server	[R421] getaddrinfo start -- flags: 0xC000D000, ifindex: 0, protocols: 0, hostname: google.com, options: 0x8 {use-failover}, client pid: 545 (com.apple.WebKi), delegator pid: 463 (<CFBundleName>)
default	2026-03-06 08:10:29.583518 +0100	mDNSResponder	resolver	[Q65194] Received acceptable 44-byte response from 192.168.179.1 over UDP via en0/13 -- id: 0x533C (21308), flags: 0x8180 (R/Query, RD, RA, NoError), counts: 1/1/0/0, google.com. IN A?, 285 IN A 172.217.17.206
default	2026-03-06 08:19:53.020864 +0100	com.apple.WebKit.Networking	connection	[C1 83F90D07-2D61-4158-A073-C82071955008 google.com:443 quic-connection, bundle id: <CFBundleIdentifier>, url: https://google.com/, definite, attribution: developer, context: com.apple.CFNetwork.NSURLSession.{FC11B685-7D67-4806-80B1-6E2559DC8AA4}{(null)}{Y}{3}{0x20e0344a0} (sensitive), proc: 1F873F6E-9E6F-3D35-A95D-C72E62C50C26, effective proc: 888D3A38-707B-33BC-944C-0143FC68835D, delegated upid: 0, pid: 814, attribution context: google.com] start
info	2026-03-06 08:19:53.024946 +0100	com.apple.WebKit.Networking	connection	nw_endpoint_resolver_handle_alternative [C1.1.1 google.com:443 in_progress resolver (satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi, LQM: good)] Discovered alternative google.com:443 using tcp
info	2026-03-06 08:19:53.024960 +0100	com.apple.WebKit.Networking	connection	nw_endpoint_resolver_handle_alternative [C1.1.1 google.com:443 in_progress resolver (satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi, LQM: good)] Discovered alternative google.com:443 using quic
info	2026-03-06 08:19:53.024986 +0100	com.apple.WebKit.Networking	connection	nw_endpoint_transform_receive_report_block_invoke [C1.1 google.com:443 in_progress transform (satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi, LQM: good)] updated endpoint alternatives allow quic, restarting
default	2026-03-06 08:19:53.029119 +0100	com.apple.WebKit.Networking	quic	quic_conn_initialize_inner [C1.1.2.1:2] [-987721dfe9544d2a] created QUIC connection (spin bit enabled)
info	2026-03-06 08:19:53.100833 +0100	com.apple.WebKit.Networking	quic	quic_conn_process_inbound [C1.1.2.1:2] [-f87721dfe9544d2a] unable to parse packet (decryption keys may not be ready)

If it’s a QUIC connection and the logs has a com.apple.WebKit.Networking subsystem, it’s almost certainly HTTP/3. Have you tried the HTTP Traffic instrument? See Analyzing HTTP traffic with Instruments.

Share and Enjoy

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

I have, but the HTTP Traffic Instrument does not seem to record anything, I just get Network Connections:

the HTTP Traffic Instrument does not seem to record anything

Indeed. I had just assumed that it’d work for requests generated by a web view, but I tried that here today and it doesn’t seem to be the case )-:

Still, that’s more evidence that this QUIC traffic is coming from a web view, which is very likely to be HTTP/3. And you should be able to intercept that with a debugging HTTP proxy. Have you tried that already?

Share and Enjoy

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

Yes, that's the first thing I tried after tcpdump when I saw there were encrypted QUIC packets in the trace file. I could not get my device to connect to mitmproxy running on my Mac though, and running Proxyman directly on the device did not capture anything interesting.

OK. Lemme explain how I’d tackle this and then you can either try it yourself or, if you’ve tried it already, share your experience.

I typically test this stuff with a small test project. I set it up to run a request via URLSession and also load a page via a web view. I then run my debugging infrastructure against that test app. If things work there, I can run the same setup against my real app with some confidence that my debugging setup is working. OTOH, if I can’t get the results I expect with my test app, I know that there’s something wrong with my debugging setup.

I haven’t tried mitmproxy recently, but the last time I did it worked a treat.

Share and Enjoy

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

I haven’t tried mitmproxy recently, but the last time I did it worked a treat.

I don't know what I'm doing wrong honestly, but if I configure a manual HTTP proxy I always end up with "No Internet Connection"

I was able to get this working today:

  1. On my Mac, running macOS 26.2, I downloaded the Mac version (mitmproxy-12.2.1-macos-arm64.tar.gz).

  2. I unpacked it.

  3. I moved it to the Applications folder.

  4. And launched it (which opens a Terminal window).

  5. It creates its CA (certificate authority) certificates in ~/.mitmproxy . I check that was all present:

    % ls -l ~/.mitmproxy 
    total 48
    -rw-r--r--@ 1 quinn  staff  1172 13 Mar 12:05 mitmproxy-ca-cert.cer
    -rw-r--r--@ 1 quinn  staff  1035 13 Mar 12:05 mitmproxy-ca-cert.p12
    -rw-r--r--@ 1 quinn  staff  1172 13 Mar 12:05 mitmproxy-ca-cert.pem
    -rw-------@ 1 quinn  staff  2384 13 Mar 12:05 mitmproxy-ca.p12
    -rw-------@ 1 quinn  staff  2847 13 Mar 12:05 mitmproxy-ca.pem
    -rw-r--r--@ 1 quinn  staff   770 13 Mar 12:05 mitmproxy-dhparam.pem
    
  6. On a victim device running 26.2…

    IMPORTANT This process involves changing system-wide trust settings. Given that, it’s not appropriate for a device you actually care about.

  7. I launched Safari and open a private browsing tab (this helps with subsequent steps).

  8. In Settings > Wi-Fi > My Network > Configure Proxy, I selected Manual, and entered my Mac’s IP address and port 8080.

  9. Back in Safari, I went to http://mitm.it.

  10. I tapped iOS > Get “mitmproxy-ca-cert.pem” and agreed to the download.

  11. In Settings > General > VPN & Device Management > mitmproxy, I ran through the install sequence.

  12. In Settings > About > Certificate Trust Settings, I enabled the “mitmproxy” CA.

  13. Back in Safari, I created a new tab and entered https://mitmproxy.org.

  14. In Terminal on my Mac, I saw those requests being proxied.

    Note If you press z, you can clear the list of requests which makes it easier to see the new ones.

  15. Back in Safari, I hit the refresh button and watched the requests continue to be proxied.

Neat-o!


I hit one really weird gotcha during this exercise. In step 13 I originally tested with https://example.com. That failed with a 502 Bad Gateway error. I suspect this is some special case within mitmproxy, because it only seems to affect that site.

Share and Enjoy

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

Thank you for the detailed instructions, I still cannot get it to work though. My Mac is running macOS 15.7.4 and my iPhone is on iOS 26.3.1, but step 9 invariably fails. I even tried messing with the system firewall settings, allowing all incoming connections to mitmproxy and disabling the firewall altogether, but still no luck.

Do you work in a managed environment?

I sometimes see reports like by folks who work in high-security industries, like health or finance. Their network, Mac, or device is locked down in some way that breaks this tooling. It’s hard to offer specific advice in that case, because these setups are very site specific, but I do have a few general hints:

  • If you have a Mac laptop, you can relocate it to a different network. For example, you might run this test at home.
  • Rather than running the proxy on your main work Mac, run it on a ‘victim’ Mac. For example, I often have great success using Mac-on-Mac virtualisation.
  • Test with a victim ‘device’ that’s unmanaged. Or if you test device is managed, try a different device, like your own personal iPhone.

Share and Enjoy

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

This is slightly embarrassing, but it turns out that I was using a wi-fi that basically blocks everything except ports 80 and 443. After I changed networks it worked as you described.

Regarding the suspicious traffic however I am none the wiser since apparently the connection is secured using some sort of pinning; running mitmdump reveals:

client connect
server connect google.com:443 (142.251.39.238:443)
Client TLS handshake failed. The client disconnected during the handshake. If this happens consistently for google.com, this may indicate that the client does not trust the proxy's certificate.
client disconnect
server disconnect google.com:443 (142.251.39.238:443)
I was using a wi-fi that basically blocks everything

Hey hey!

And, yeah, I see stuff like that all the time (-:

apparently the connection is secured using some sort of pinning

Interesting.

The weird part about this is your suspicion that the traffic is coming from within the web view, but it’s not obvious code running in the web view — so JavaScript, basically — could implement pinning.

So, I think it’d be worthwhile double checking the origin of this network connection. With mitmproxy you should be able to get the source IP and port number of the request. And you can then use RVI to track the originating process. RVI puts this in packet metadata, which you can display by running tcpdump with the -k option. See the tcpdump man page for details.

Share and Enjoy

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

Recording a Packet Trace
 
 
Q