One of the most frustrating things as a frontend developer is when you are receiving incorrect data. You don’t know whether the problem lies with your application, or the backend services. The easiest way to validate this is to pretend to be a hacker. You can stage a man-in-the-middle attack on your own application. Debugging using tools like Fiddler or Charles can be used to inspect the traffic from your application. Unfortunately, the same effort that goes into protecting apps from such attacks, also means that it is harder for developers to setup Fiddler debugging.
In this post I’ll walk through setting up Fiddler debugging for a Xamarin.Forms application. The same basic approach will work for a native or Xamarin iOS/Android application as well. For this post I’ve created an application using the Blank Xamarin.Forms template that comes with Visual Studio 2019. I’ve selected to target all three platforms.
In the OnAppearing method in the MainPage of the Xamarin.Forms application, I’ve added some basic code to retrieve a string for a Https endpoint. We’ll use a Https endpoint on the assumption that if we can intercept Https then we can also intercept Http traffic.
protected override async void OnAppearing() { base.OnAppearing(); var client = new HttpClient(); var users = await client.GetStringAsync("https://reqres.in/api/users?page=0"); Debug.WriteLine(users); }
Setting Up Fiddler Debugging
Before we get started with the individual platforms, it’s worth checking your configuration for Fiddler:
- You need to make sure you have setup Https traffic decryption. I’m not going to repeat the documentation, so check out how to Configure Fiddler to Decrypt HTTPS Traffic.
- You’ll also need to setup Fiddler debugging for remote traffic. This can be done by opening the Options window. Under the Connections tab, make sure the “Allow remote computers to connect” checkbox is checked. If you’re running Skype, or some other communication tools, it may have jumped onto the default port configured in Fiddler. In this case you can adjust the “Fiddler listens on port”.
Windows (UWP)
I’ll start with Windows, because it’s relatively straight forward to get setup. With Fiddler running, you can run the UWP project from within Visual Studio and Fiddler debugging will work. Fiddler will capture the Https traffic without any further configuration or setup.
In some cases, you need to make sure your application is added to the exemption list, so that traffic can be routed to the local machine. For more information see the blog post Revisiting Fiddler and Win8+ Immersive applications. To check this, click the WinConfig button in the top left corner of the Fiddler interface.
Locate your application and confirm that there is a check in the box next to your application. If it’s not checked, check the box, and then click Save Changes.
One other issue I’ve seen but can’t reproduce reliably, is that sometimes when you run your application from Visual Studio it unchecks the box in the WinConfig in Fiddler. If for some reason you no longer see traffic in Fiddler for your application, go back and double check the exemption list in Fiddler.
Diagnosing Issues with Fiddler on Windows
When configuring Https traffic decryption, you’ll be prompted to install and trust the Fiddler root certificate. If you don’t accept all the prompts, Fiddler debugging for Windows applications will not work. Windows traffic debugging works without any further configuration because the Fiddler root certificate is trusted on the machine running Fiddler.
If you’re attempting to run the Windows application on a different machine than the one running Fiddler, you’ll need to install and trust the Fiddler root certificate. This is in addition to setting the remote machine as a proxy, which is a topic for another post. Navigate to http://[ipaddress]:[port] where [ipaddress] is the ip address of the machine running Fiddler and the [port] is the port number that Fiddler is listening on. Do NOT use https as this site is http only. You should see a screen similar to the following image – if you don’t, make sure you check that Fiddler is running!!
Click on the FiddlerRoot Certificate and install as a Trusted Certificate Authority on the Local Machine. This should allow your Windows application to trust Fiddler.
iOS Fiddler Debugging
Next up is iOS and in this case we’re going to use the iOS simulator. The same process should work with any iOS device that’s on the same local network as the machine running Fiddler. There are two steps to setup iOS for traffic debugging:
- Trust the Fiddler root certificate, and
- Set the http proxy to use the machine running Fiddler.
To setup the simulator, first launch the iOS application from Visual Studio. If you’re on Windows, this will launch the remote viewer for the simulator. Once the simulator is running, stop debugging and we’ll setup the simulator for traffic debugging.
Trusting the Fiddler Certificate
Navigate to http:[ipaddress]:[port] (eg http://192.168.1.109:8888) to load the Fiddler echo page. Then click on the Fiddler Certificate link. Follow the prompts to download and install the certificate.
In addition to downloading the certificate you also need to install it. Go to Settings / General / Profile and click through on the FiddlerRoot profile in order to Install it.
The Fiddler root certificate needs to be trusted as a root certificate. Go to Settings / About / Certificate Trust Settings and toggle the switch next to the FiddlerRoot certificate. Fiddler generates a certificate for each site you go to that is derived from the root certificate, so the root certificate needs to be installed as a trusted certificate.
The only difference between a real iOS device and the simulator is that on a real iOS device you can set a network proxy. There are online tutorials, such as this one, for instructions on setting a proxy. Unfortunately, setting up a proxy this isn’t configurable on the simulator. If you want to use a proxy in the simulator, you can set the proxy on the mac running the simulator but this would affect all traffic on the mac. Alternatively, when running on the simulator, we can adjust the HttpClient to use a WebProxy using the following code:
var handler = new HttpClientHandler(); handler.Proxy = new WebProxy("192.168.1.109", 8888); var client = new HttpClient(handler);
Running the iOS application should show network traffic in Fiddler debugging window. You should still see the returned data printed out in the Output window (ie from the Debug.WriteLine statement).
Android Fiddler Debugging
For Android I’m going to use the Android Simulator. Real devices should behave similarly, assuming they’re connected to the same local network as the machine running Fiddler.
Unlike iOS, that will use any proxy configured for the device, for Android you need to explicitly opt in to use a proxy in your code. You’ll need to use code similar to the following on both emulator and real devices:
var handler = new HttpClientHandler(); handler.Proxy = new WebProxy("192.168.1.109", 8888); var client = new HttpClient(handler);
What’s a little scary about this code is that it “just works”. You might be thinking that this is a good thing. However, it does raise the question of how much of the system security model does the Microsoft built HttpClientHandler respect. What I would have expected is an SSL fail exception because the Fiddler root certificate isn’t trusted by the emulator. Furthermore, the application is not configured to use any user certificates.
The other thing to point out here is that you should not be using the HttpClientHandler. I’ve discussed this in my previous post on working with the HttpClient. Let’s change our code by moving it into the OnCreate method of the Android head project. We’ll also change over to using the AndroidClientHandler.
protected override async void OnCreate(Bundle savedInstanceState) { ... var handler = new AndroidClientHandler(); handler.Proxy = new WebProxy("192.168.1.109", 8888); var client = new HttpClient(handler); var users = await client.GetStringAsync("https://reqres.in/api/users?page=0"); System.Diagnostics.Debug.WriteLine(users); }
When we run the application we see the very familiar SSL handshake exception being raised, which is what we should expect. To get things to work, we now need to install the Fiddler certificate and configure the application to use user certificates.
Install the Fiddler Root Certificate
To install the Fiddler root certificate, navigate to http:[ipaddress]:[port] (eg http://192.168.1.109:8888) to load the Fiddler echo page. Click on the Fiddler Certificate link in order to download the certificate. Follow the prompts to download and install the certificate
After installing the certificate go to Setting / Security and Location / Encryption & credentials / User credentials to inspect the certificate
With the certificate installed into the user store, you need to configure the Android project to allow the use of certificates from the user store. In my post Working with Self Signed Certificates (Certificate Pinning) in Android Applications with Xamarin.Forms, I covered this in detail. The quick summary is that you need to create a network_security_config.xml file which sets the trust-anchors property (set using the debug-overrides element) to include certificates from the user store. You then need to reference this xml file from the networkSecurityConfig attribute on the application element in the AndroidManifest.xml file.
After installing the certificate and adding the network security configuration to the Android application you should now see network requests from the application appear within Fiddler debugging window.
If you are working on Xamarin apps and using netstandard, you’ll want to check out HttpTracer. Add HttpTracer to your project and pass a new instance to HttpClient for Fiddler-like http audit/debug capabilities. https://www.nuget.org/packages/HttpTracer/
Dylan, do you have a blog post or documentation showing how to use the HttpTracer in conjunction with the AndroidClientHandler and the NSUrlSessionHandler (see my post on using these with the HttpClient – https://nicksnettravels.builttoroam.com/post-2019-04-24-xamarin-and-the-httpclient-for-ios-android-and-windows-aspx/)