Skip to content

Frida scripts for Flutter apps that enable proxy support including sandbox flutter app. This repo demonstrates how to redirect and intercept Flutter app traffic (dart:io, Cupertino, NSURLSession, etc.) through a proxy (Burp, mitmproxy) using Frida, with detection scripts to identify the active networking stack.

Notifications You must be signed in to change notification settings

XDcobra/Fluttida

Repository files navigation

Fluttida – Intercepting Flutter App Traffic with Frida

This repository provides tools and Frida scripts to analyze, intercept and forward network traffic from Flutter applications via Frida. Because Flutter often bypasses system proxy settings and uses custom networking stacks, standard proxy interception fails. The scripts here help identify which client (e.g. dart:io, NSURLSession, NSURLConnection, or WKWebView) is in use and redirect traffic through a proxy for effective reverse engineering.

Fluttida - Proxy Interception for Flutter Apps via Frida

Flutter Version Frida Version Platform License Proxy Support via Frida

Quick Start

  1. Install mitmproxy or Burp Suite on your analysis machine.
  2. Export and install the proxy’s CA certificate on your iOS device, then enable full trust under Settings --> General --> About --> Certificate Trust Settings.
  3. Configure your iPhone’s Wi‑Fi proxy manually to point to your machine’s IP and chosen port (e.g. 192.168.1.5:8889).
  4. Run the proxy in standard mode (mitmproxy -p 8889) or Burp with an “Invisible Proxy” listener.
  5. Use Frida hooks to redirect Dart’s connect() calls to the proxy (e.g. frida -n YourApp -l intercept_dartio.js)
  6. Refresh the app and watch requests appear in your proxy.
  7. If traffic is still missing, check which networking stack the app uses by running any of the scripts within the frida_detect_engine folder (Dart:io, Cupertino/NSURLSession, NSURLConnection, WKWebView) and apply the corresponding hook.

Why Flutter Apps Cannot Be Intercepted with a Standard Proxy

Flutter simplifies cross‑platform development, but when it comes to network traffic, it introduces complexities that make traditional proxy interception unreliable. This document explains in detail why Flutter apps often bypass normal proxy setups, the technical background behind it, and what approaches can still work.


Overview

Flutter apps can use different networking stacks depending on the code path. The most common is the Dart‑based dart:io HttpClient. Unlike native iOS/Android clients, dart:io often ignores system proxy settings and does not perform the expected proxy handshake, which breaks standard interception with tools like Burp or mitmproxy.

  • Core issue: Many Flutter apps connect directly to target hosts without sending a CONNECT request to the proxy.
  • Result: Proxies see no traffic, TLS connections fail, or only raw socket streams appear without host context.
  • Workarounds: Transparent interception (NAT/pf/iptables), manual proxy configuration plus hooks, installing custom CA certificates, and bypassing certificate pinning.

This repo includes several scripts to make reverse engineering of flutter APIs easier.

Engine / Library Detection (iOS) Detection (Android) Intercept (iOS) Intercept (Android)
dart:io HttpClient frida_detect_engine/check_dartio.js Coming soon intercept_dartio.js intercept_dartio.js
package:http (default / IOClient) Coming soon Coming soon Coming soon Coming soon
package:http via IOClient Coming soon Coming soon Coming soon Coming soon
cupertino_http (NSURLSession) frida_detect_engine/check_cupertino.js N/A Coming soon N/A
NSURLConnection / CFURL frida_detect_engine/check_nsurl.js N/A Coming soon N/A
WKWebView / WebView frida_detect_engine/check_webview.js Coming soon Coming soon Coming soon
Android HttpURLConnection N/A Coming soon N/A Coming soon
Android OkHttp N/A Coming soon N/A Coming soon
Android Cronet (embedded) N/A Coming soon N/A Coming soon
libcurl (native) Coming soon Coming soon Coming soon Coming soon

Technical Background

Dart:io HttpClient vs. Standard Proxy Usage

  • No CONNECT handshake unless explicitly configured.
  • System proxy often ignored.
  • Direct socket calls bypass proxy‑aware APIs.

Alternative Stacks

  • Cupertino HTTP (NSURLSession) – may respect system proxy, but often configured to bypass.
  • WebView (WKWebView) – traffic depends on WebKit and system settings.
  • Native bridges – custom ObjC/Swift/Java networking stacks may ignore proxy.

TLS, HTTP/2, Certificates, and Pinning

  • Direct TLS connections cannot be intercepted by a standard proxy.
  • HTTP/2 and ALPN negotiation requires proper TLS termination.
  • ATS and certificate pinning block interception unless bypassed (see accept_all_certs.js for a general ssl pinning bypass)
  • IPv6 and QUIC/HTTP/3 introduce additional challenges.

Symptoms in Practice

  • Proxy shows no traffic.
  • mitmproxy transparent mode errors (“cannot resolve original destination”).
  • TLS handshake failures.
  • Partial visibility (only WebView traffic intercepted).

Working Approaches

System Proxy + Hooks

  • Manual proxy in Wi‑Fi settings.
  • Frida hook on connect() to force Dart traffic through proxy.
  • Install and trust proxy CA.
  • Bypass certificate pinning.

Transparent Interception (Linux/macOS)

  • Use pf or iptables to redirect traffic.
  • Run mitmproxy in transparent mode.
  • On Windows, use WSL or Burp Invisible Proxy mode.

Detecting Which Stack Is Used

  • Dart:io: Hook connect() in libsystem_kernel.dylib.
  • Cupertino/NSURLSession: Hook -[NSURLSession dataTaskWithRequest:completionHandler:].
  • NSURLConnection/CFNetwork: Hook +[NSURLConnection sendSynchronousRequest:returningResponse:error:] or CFURLConnectionCreateWithRequest.
  • WebView: Hook -[WKWebView loadRequest:].

Example App: Fluttida (example_app/fluttida)

Main screen Results screen Logs screen Pinning screen

This repository includes a small Flutter example app located at example_app/fluttida. The app is a network-stack lab and playground designed to help you test, compare, and instrument different HTTP clients and platform stacks while using Frida.

SSL pinning lab (example app)

  • Enable/disable pinning per stack (dart:io, package:http, Android HttpURLConnection/OkHttp/Cronet, native libcurl).
  • Switch between SPKI (public key) and certificate hash pins; import/export pins as base64.
  • UI logs show server cert/SPKI hashes alongside configured pins for quick debugging.

How this app helps with Frida

  • Playground for multiple stacks: run the same request via dart:io, package:http, iOS NSURLSession (via cupertino_http), Android native stacks (HttpURLConnection, OkHttp, Cronet), and a headless WebView — compare results side-by-side.
  • Safe instrumentation target: use the app on a device or emulator as a controlled target for Frida scripts so you can attach hooks without affecting production apps.
  • Validate hooks & proxying: reproduce real-world scenarios (headers, redirects, TLS behavior) and verify that your Frida scripts (e.g. intercept_dartio.js) correctly redirect or modify traffic.
  • Debugging helper: the app shows unified results (status, body, durationMs, error) and logs, making it easy to observe the effects of your live instrumentation.

Quick steps to use the example app with Frida

  1. Run the example app on a device or emulator:
cd example_app/fluttida
flutter pub get
flutter run
  1. Attach Frida and load a detection or interception script, for example:
# list processes and attach by name or PID
frida-ps -Uai
frida -U -n Fluttida -l frida_detect_engine/check_dartio.js
# or to intercept
frida -U -n Fluttida -l intercept_dartio.js
  1. Use the app UI to run requests across different stacks and inspect the Results/Logs to confirm whether your hooks or proxying are working as intended.

Native libcurl stacks (Android NDK and iOS)

The lab app also includes native libcurl stacks to compare behavior outside the platform HTTP clients. In case you want to include your own libcurl builds, read the following how-to:

  • Android NDK (libcurl)

    • See android/README-libcurl.md for full setup instructions (libraries, headers, CA bundle).
    • In the app, select the stack "Android NDK (libcurl)".
  • iOS Native (libcurl XCFramework)

    • Place the XCFramework under:
      • example_app/fluttida/ios/Frameworks/libcurl.xcframework
    • The project is wired to link this XCFramework and expose a method channel stack named "iOS Native (libcurl)".
    • Build variants:
      • Secure Transport (DarwinSSL): libcurl can be built against the Apple TLS stack and will use the system trust store (no OpenSSL files required).
      • OpenSSL (static): the repo also supports building libcurl against OpenSSL. If you use the OpenSSL variant, you must bundle the OpenSSL static libraries and a CA bundle with the app (instructions below).
    • If you build your own XCFramework, ensure device (arm64) and simulator (arm64/x86_64) slices are present.

    OpenSSL (static) packaging (when libcurl was built with OpenSSL):

    • Copy these static libs into the app so the app can link at build time:

      • example_app/fluttida/ios/Runner/Frameworks/OpenSSL-static/iphoneos/libssl.a
      • example_app/fluttida/ios/Runner/Frameworks/OpenSSL-static/iphoneos/libcrypto.a
      • example_app/fluttida/ios/Runner/Frameworks/OpenSSL-static/iphonesimulator/libssl.a
      • example_app/fluttida/ios/Runner/Frameworks/OpenSSL-static/iphonesimulator/libcrypto.a
    • CA bundle: add a CA bundle (for example cacert.pem from curl) to:

      • example_app/fluttida/ios/Runner/Resources/cacert.pem The app sets CURLOPT_CAINFO to the bundled cacert.pem at runtime (see NativeHttp.mm). Ensure the file is included in the Runner target's "Copy Bundle Resources" so it is available at runtime.
    • Project wiring: the project has been updated to add library search paths and link flags for the OpenSSL-static folders and to copy cacert.pem into the app bundle. If you prefer, you can instead add the four .a files as file references under the Runner target.

Licenses

  • The app includes license files under the XCFramework (e.g., licenses/COPYING-curl.txt). Keep third‑party license texts with distributed binaries.

About

Frida scripts for Flutter apps that enable proxy support including sandbox flutter app. This repo demonstrates how to redirect and intercept Flutter app traffic (dart:io, Cupertino, NSURLSession, etc.) through a proxy (Burp, mitmproxy) using Frida, with detection scripts to identify the active networking stack.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •