Debugging iOS apps with Zaproxy

Reading Time: 4 minutes

The other day I was debugging a really nasty bug that happens only in our iOS app. I was really frustrated because I couldn’t figure out why it happens. Everything looks good when debugging the iOS code, but for some reason – the server failed to deserialize the request body. I freaked out – nothing I tried seems to solve the issue. If only there was an easy way to view the actual request and response, maybe I could understand what the issue was…

This is where a proxy comes in handy: A proxy can inspect the traffic and print it an easy to understand manner. There are a lot of available proxies you can use (like Charles (commercial) or Fidler), but OWASP Zaproxy (Zap) is the best open source proxy that I know. Let’s see how easy it is to set it up:

Step 1 – Install Zap’s Root CA Certificate

Installing the root CA certificate on our iOS device is required in order to allow Zap to inspect HTTPS traffic – by acting as a TLS termination proxy. To install it, start by exporting the root CA from Zap. Go to Zap, and click Tools -> Options -> Dynamic SSL Certificates to open this menu:

Zap's Dynamic SSL Certificates Menu
Zap’s Dynamic SSL Certificates Menu

Click the little save button, and choose where to save the certificate. Now it’s time to import it – this is a simple as dragging the certificate file and dropping it inside the simulator. Once you drop the certificate, a new Safari window will appear:

Importing a certificate into iOS simulator
Safari asking if to install the certificate

Press allow – only because you know what is this certificate. Careful before doing something similar on your personal phone, or with a certificate that you’re not trusting! Now you should see the following window:

Certificate Installation Window
Certificate Installation Window

Press the install button, and again on the install button in the next window – and we’re almost done! Now it’s important to activate the certificate – otherwise, it will not be trusted by iOS. Go to Settings -> General -> About -> Certificate Trust Settings:

iOS Certificate Trust Settings
iOS Certificate Trust Settings

Press the little switch button near “OWASP Zed Attack Proxy Root CA”. Doing so will show another dialog box. Press continue – and now you’re done! From now, Zap can intercept TLS traffic from an app running on this Simulator πŸ‘πŸ½ πŸ‘πŸ½

Before moving to the next step – a quick reminder: If you’re app use certificate pinning, the above will not work. Certificate pinning protects your app from someone trying to intercept TLS traffic – and this is why you want it. Make sure to disable it in you’re app code before continue reading!

Step 2 – Configure Proxy Settings

The next step is to configure iOS simulator to use Zap as a proxy for all outgoing requests. As iOS simulator uses the OS proxy settings, this is done by changing them. Open System Preferences -> Network and choose your active network connection (e.g. Wifi). Click the advance button and go to proxies tab:

Mac OS Proxy Settings
Mac OS Proxy Settings

Make sure you check both Web Proxy and Secure Web Proxy and set the correct details of Zap on both of them. If Zap is running on your local machine – the settings in the picture should work. Now press the “ok” button and “apply” on the main network settings and you’re done!

Step 3 – Profit!

It’s time for the fun part! Open any app on the simulator – and you should see the requests on Zap proxy. For example, this is what I see on Zap when I try to open my blog using Safari browser on the simulator:

Zap proxy requests to my website
Zap proxy requests to my website!

You can easily see all the requests and response nicely printed. Zap support advanced features like replaying the request. This is useful if you want to take the product request and send it to a service running locally. Check out the context menu on the request to see everything Zap can do. One last bonus point: because we’re using Zaproxy – we also get a free security test for our app. Make sure to take a look at the alert tab – you might discover a security issue in you’re app!

Wrapping up – finding the bug!

After I proxied the requests from my app, I spotted the bug immediately: For some reason, our iOS app uses camel case when serializing while all the other clients use Pascal case for serializing πŸ€¦πŸ½β€β™€οΈIt was a lot harder to spot this bug without a proxy! Credit: This post is inspired by this great post showing how to configure Charles proxy for iOS simulator. The post helped me understand how to import the certificate but requires some modification to work also with Zaproxy. Thank you for the help!

Leave a Reply

Your email address will not be published. Required fields are marked *