Our proxy captured zero bytes from a mobile app. Here is how we got the traffic.

An ordinary proxy captured nothing from a Flutter shopping app. How we patched the build and redirected traffic to read the API.
Case study // AI Security Toolkit, a shopping app

Our proxy captured zero bytes from a mobile app. Here is how we got the traffic.

A Flutter app ignores the phone's trust store and its proxy. Ordinary interception sees nothing.

A shopping app built with Flutter, for iOS and Android, sat on a headless e-commerce backend. We pointed our usual intercepting proxy at it and captured nothing at all.

0bytes captured with an ordinary proxy
1.4 MBof decrypted API traffic once we fixed it
7low static findings, almost all of the app's issues
0cross-account reads that succeeded
Tudor Brad working on a laptop in the BetterQA office
Tudor Brad, BetterQA co-founder, in the Cluj-Napoca office.

Why the proxy saw nothing

Flutter does not use the phone's certificate store and does not follow the system proxy. The app's own requests go straight out, so an intercepting proxy sees only background traffic from the operating system.

Switching the proxy on, installing its certificate and driving the app produced an empty capture on both platforms.

How we got the traffic

On Android we patched the app to switch off certificate checks, then used the emulator's own network rules to redirect outgoing traffic to a proxy running in reverse mode, which needs no special rights on the host.

On iOS the only build that can run on a simulator is a simulator build, so we needed one of those rather than a device build. The result was 1.4 MB of decrypted API traffic.

Other obstacles

One of the testing tools errored on large iOS builds, so that part stayed manual. The target's network gateway also blocked our address once after live probes, which cost time and is worth planning for.

What we found, and why the quiet result is the value

Seven low findings from static analysis, and two more on the live pass: no email verification at sign-up and a screen that overflowed. That is a good result.

Login errors did not reveal which accounts exist, the password-reset response was generic, and changing a password needed the old one. An access test between two throwaway accounts, editing and deleting an address across accounts, returned a refusal on every attempt.

What we wrote down

The method now lives in a written recipe, so the next Flutter app starts with traffic on day one instead of day three. A clean report from a test that could not see traffic is not clean, so the first thing to check is that the capture has bytes in it.

Want your mobile app tested with real traffic, not a guess?

We check that our own test can see the app before we say it is clean. The first month is a trial.

Talk to our team
Share the Post: