こんにちは、SSTでWeb脆弱性診断用のツール(スキャンツール)開発をしている坂本(Twitter, GitHub)です。
最近はiOSアプリによるHTTP通信を診断することが増えてきました。 診断のために iOS のWiFi設定から Burp 向けにHTTP Proxy を設定しますが、一回の設定で素直にBurpで通信を確認できないアプリもあります。 Safari経由では Burp プロキシを通ることを確認できているのに、アプリ側のHTTP通信が Burp を通らない(ように見える)のです。 「もしやこのアプリ、WiFiのHTTP Proxy設定に対応していないのでは?」と焦ったりもしますが、何回か試してるといつのまにかBurpで通信ログを取れていたりもするので、焦らずにトライ&エラーが必要なようです。
そもそも iOS アプリ用のHTTP通信ライブラリにおいて、WiFi設定からの HTTP Proxy をサポートしているのはどれくらいあるのでしょうか?
この疑問についてざっとネット上を検索してみたので、簡単に整理して調査メモとして公開します。
注意:筆者は iOS 開発をしたことがなく、Objective-C や Swift も触ったことがありません。 そのため、本調査メモには勘違いや誤り等が含まれている可能性があります。 どうかご容赦のほどお願いします。 (間違いに気づかれた方は、よろしければTwitterのDMなどでこっそり教えてください)
またリンクURLやリンク先ページのタイトルは 2021-07 時点のものになります。 将来変更される可能性があるのでご注意ください。
- 「WiFiのHTTP Proxy設定に対応」とはどういうことか
- iOSにおけるHTTP通信ライブラリ
- NSURLSession/URLSession クラス
- Alamofire
- AFNetworking
- まとめ
- 補足: Flutter について
「WiFiのHTTP Proxy設定に対応」とはどういうことか
調査の前に「WiFiのHTTP Proxy設定に対応」の中身について確認します。
iOSでは WiFi 設定画面から HTTP Proxy を設定します。 アプリごとに個別に HTTP Proxy 設定機能があるわけではなく、システム全体として WiFi 設定の中に HTTP Proxy 設定が組み込まれている形になります。 また、HTTP Proxy 設定が有効化されていればそれにあわせて HTTPリクエストをカスタマイズしたり接続先をProxyに切り替える 必要があります。 アプリケーション開発者の視点に立つと、そのHTTP通信ライブラリを使えば特別な設定やコーディングなしで、自動でこれらに対応してくれると嬉しいです。
まとめると「WiFi のHTTP Proxy 設定に対応」の中身とは、
- iOS の WiFi の HTTP Proxy 設定を参照して、
- それに応じて自動でHTTPリクエストのカスタマイズや接続先を切り替えてくれて、
- アプリケーション開発者からは特別な設定やコーディング無しで自動でそれらに対応してくれる。
これらの条件を満たすこと、と考えることができます。
条件を満たしたHTTP通信ライブラリを使えば、開発したアプリはそのまま WiFi のHTTP Proxy 設定を使うはずです。 診断の観点からも、素直に Burp を通せるようになるので助かります。 今回はそうした観点で調査してみました。
iOSにおけるHTTP通信ライブラリ
まず iOS におけるHTTP通信ライブラリはどんなものがあるか検索してみました。
ios - How do I make an HTTP request in Swift? - Stack Overflow
標準ライブラリのみで簡単にAPIクライアントを実装する(Swift) - Qiita
NSURLSession/URLSession, AFNetworking, Alamofire というライブラリが見つかりましたので、これらについてProxy対応状況を調べてみます。
NSURLSession/URLSession クラス
iOSが提供する標準のHTTP(S)通信ライブラリで NSURLSession/URLSession クラスがあります。
- https://developer.apple.com/documentation/foundation/nsurlsession
- https://developer.apple.com/documentation/foundation/urlsession
これら公式ドキュメントの "Protocol Support" セクションで、ユーザによるシステム設定に基づくプロキシやSOCKSゲートウェイ処理をサポートしている記述がありました。 iOS における WiFi のHTTP Proxy 設定まで含むかどうか、実際にアプリを作って検証してみないと断言できませんが、対応している確度は非常に高いと考えます。
HTTP通信の扱い全体については "URL Loading System" と題した以下のページが全体的なガイドブックとなっている模様です。
これを使えば、プログラム側で特別な設定をすることなく、iOSのWiFi設定のProxyを参照して自動で Proxy 対応をしてくれるものと思われます。
プログラム側で意図的に Proxy を設定したい場合は、以下の記事が参考になりそうでした。
"How can I connect to a proxy server?" - Apple Developer Forums
NSURLSessionで任意のProxyを使う - Qiita
Alamofire
Alamofire は Swift用のHTTP通信ライブラリです。
- Alamofire : https://github.com/Alamofire/Alamofire
iOSの URLSession クラスの上に構築されている模様なので、デフォルトで WiFi設定のProxyを参照してくれるものと思われます。
プログラム側で意図的に Proxy を設定したい場合は、以下の記事が参考になりそうでした。
Can Alamofire Support proxying HTTP requests? ・ Issue #282 ・ Alamofire/Alamofire
Swift: Alamofire HTTP Proxy - Stack Overflow
macos - Setting proxy with Alamofire Session - Stack Overflow
AFNetworking
AFNetworking は iOS や macOS アプリ用のHTTP通信ライブラリです。
- AFNetworking : https://github.com/AFNetworking/AFNetworking
iOSの URLSession クラスの上に構築されている模様なので、デフォルトで WiFi設定のProxyを参照してくれるものと思われます。
以下の記事でも URLSession そのままなので Proxyを通せるようなことが書いてあります。
ios - AFNetworking HTTP Proxy - Stack Overflow
プログラム側で意図的に Proxy を設定したい場合は、以下の記事が参考になりそうでした。
AFNetworking 2.xでプロキシを使う - Qiita
http proxy ・ Issue #1945 ・ AFNetworking/AFNetworking
ios - how to set proxy details using AFNetworking - Stack Overflow
まとめ
- 以下のHTTP通信クラスやライブラリについて Proxy サポート状況を調べました。
- NSURLSession/URLSession
- Alamofire
- AFNetworking
- NSURLSession/URLSession は特別な設定無しで WiFi 設定のProxyに対応していると思われます。
- Alamofire, AFNetworking も URLSession をベースに開発されているため、同様に WiFi設定のProxyに対応していると思われます。
これらのクラスやライブラリを使えば、特別なコーディングや設定無しで、iOSの WiFi の HTTP Proxy 設定に追従してくれるものと思われます。
補足: Flutter について
本記事ではライブラリまでを範囲として調査しました。 クロスプラットフォームな言語やフレームワークまでは調査していません。 その中には独自にHTTP通信処理を実装しているがゆえに、 iOS の WiFi の HTTP Proxy 設定を参照しなかったり、Proxy設定に応じたHTTPリクエストのカスタマイズ・接続先切り替えに未対応なケースがあるかもしれません。
Dart 言語 で開発されているクロスプラットフォームなフレームワーク、Flutter 製のアプリがそうでした。 アプリケーションのソースコード上でProxy設定をすれば、HTTPリクエストのカスタマイズ・接続先切り替えは対応しているようです。 ただ肝心の、iOS の WiFi の HTTP Proxy 設定を参照しません。 iOS側でBurpのProxy設定をしても、HTTP通信が取れないのです。
このトラブルに遭遇したときは、対象アプリの開発者と相談し、以下の資料も参考にしつつ iOS の WiFi の HTTP Proxy 設定を参照するように改良してもらいました。 結果として無事に Burp で HTTP 通信を取れるようになりました。
Flutter移行の苦労と、乗り越えた先に得られたもの - Speaker Deck
, p94 参照
詳細については、記事を分けて紹介します: techblog.securesky-tech.com