플러터에서 Proxy 툴 설정

1. 왜 Flutter에서는 시스템 프록시가 안 먹히는지

핵심 원인은 “플러터는 안드로이드/iOS 시스템 네트워크 스택을 안 타고, Dart VM이 직접 소켓을 연다”는 점입니다.

  • 일반 네이티브 앱

    • OkHttp, HttpURLConnection(안드로이드), URLSession(iOS) 같은 OS 네트워크 스택 위에서 동작.​

    • 이 스택이 시스템 프록시, Wi‑Fi 프록시, 환경변수(http_proxy 등)를 자동으로 반영.

    • 그래서 단말에 프록시만 잡아도 Burp, Charles가 자연스럽게 중간에 낀다.​

  • Flutter/Dart 앱

    • Dart dart:io 레벨에서 Socket/HttpClient를 이용해 직접 TCP 소켓을 연다.​

    • 안드로이드/ iOS 네트워크 스택의 “프록시 설정을 읽는 계층”을 우회해서 바로 서버로 붙는 구조.

    • 결과적으로:

      • 시스템 프록시, Wi‑Fi 프록시, 브라우저 프록시 설정 → 전부 무시.

      • Burp/Charles 입장에서 보면 “이 기기에서 프록시를 안 쓰는 앱이 직접 서버에 붙어버리는 상황”이라 트래픽이 안 잡힌다.

즉, Flutter의 dart:io는 안드로이드/iOS의 Wi-Fi 프록시 설정을 무시하고 서버에 직접 연결된다.

왜 이런가? (비유로 쉽게)

집에서 Wi-Fi 프록시를 "우체부(프록시)"로 설정했다고 하자.

  • 네이티브 앱 (일반 앱): "우체부한테 편지 줘!" → OS가 자동으로 우체부 찾아줌 ✅

  • Flutter/Dart: "직접 주소 찾아가!" → Dart VM이 자체 TCP 연결 → 우체부 무시 ❌

핵심 이유: Dart는 웹·모바일·데스크톱 하나의 코드로 동작해야 하므로, iOS만의 "시스템 프록시 읽기" API를 쓰면 안 된다.​

네트워크 흐름 비교 (시각화)

플랫폼별 동작표 (한눈에)

앱 유형
프록시 따름?
이유
비유

네이티브

✅ 자동

OS 네트워크 스택 사용

택배회사 물류센터 거침

Flutter dart:io

❌ 우회

Dart VM 자체 TCP

개인 택배 직접 배송

해결책

코드로 설정

client.findProxy()

수동 주소 입력


2. 인증서/SSL 때문에 더 어려운 이유

프록시 설정을 억지로 우회해도, HTTPS 구간에서 한 번 더 막힙니다.

  • Flutter/Dart는 OS의 CA 저장소 대신 자체 인증서 검증 로직/저장소를 쓰는 구조라, 단말에 Burp/Charles CA를 설치해도 바로 신뢰하지 않는다.

  • 그래서 프록시를 통해 HTTPS를 중간에서 복호화하려고 하면, SSL 핸드셰이크 단계에서 인증서 검증 실패로 에러가 난다.

  • 보안 진단/리버스 영역에서는 BoringSSL, Dart의 SSL 검증 함수(예: ssl_crypto_x509_session_verify_cert_chain)를 후킹/패치해서 검증을 우회하는 식으로 SSL Pinning/인증서 체크를 해제한다.

요약하면, Flutter 앱은

  1. 프록시 설정 계층을 우회해서 직접 소켓을 열고,

  2. OS CA가 아니라 자체 검증 로직을 사용해서 “프록시 두 번 막는 구조”가 된다.


3. 개발자가 디버깅용 프록시를 쓰고 싶을 때 (정상적인 방법)

실제 서비스 코드 기준으로는, Dart 레벨에서 명시적으로 프록시를 설정해야 한다.​

  • Flutter는 HttpOverrides를 사용하지 않으면 HTTP 패킷 캡처, 프록시 서버 사용이 안 된다고 정리되어 있다.​

  • 즉, 시스템 프록시에 의존하지 말고, 앱 진입점(예: main())에서 전역 HttpClient를 프록시로 우회하도록 세팅해야 한다.​

예시 설명 (코드 없이 개념만):

  • HttpOverrides.global에 커스텀 구현을 넣어서

    • 모든 HttpClient 생성 시 findProxy를 통해 HOST:PORT 프록시로 보내도록 설정

    • 필요하다면 badCertificateCallback으로 프록시의 MITM 인증서를 허용

  • 이 상태에서 Burp/Charles를 해당 HOST:PORT로 띄우면 Flutter 앱의 HTTP/HTTPS가 정상적으로 프록시를 거친다.​

이건 “보안 우회”가 아니라 개발자 디버깅용 공식 패턴이기 때문에, 진단/테스트 환경에서 쓰기 좋은 방법이다.​


4. 보안 진단/우회 관점에서 쓰는 기법 (참고용)

실제 모의해킹/보안 진단에서는 소스 수정이 불가능하니, 아래와 같은 기법을 쓴다.

  • APK/IPA 변조 도구 사용 (예: reflutter 등)

    • Flutter 엔진 바이너리에서 소켓 생성, SSL 검증, SSL Pinning 부분을 패치해서 강제로 프록시로 흘려보내거나 검증을 항상 성공 처리.

  • 중간 VPN/서버 + iptables 리다이렉트

    • 단말에서 VPN으로 중간 서버에 연결 → 그 서버에서 iptables로 80/443 트래픽을 Burp 포트로 리다이렉트.​

    • Flutter가 시스템 프록시를 무시해도, 네트워크 레벨에서 강제로 중간 노드를 통과시키는 구조.​

  • Frida 등 동적 후킹

    • Flutter 엔진/BoringSSL의 인증서 검증 함수 반환값을 후킹해서 항상 “검증 성공”으로 바꾸는 방식.

Last updated