Open6

ユーザーエージェントについての調査

kamimikamimi

そもそもUser Agentとは

User-Agent リクエストヘッダーは、サーバーやネットワークピアがアプリケーション、オペレーティングシステム、ベンダーや、リクエストしているユーザーエージェントのバージョン等を識別できるようにする特性文字列

https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/User-Agent

「特別そう設定されていない限り、各リクエストにUser-Agentフィールドを付与して送るべき」

A user agent SHOULD send a User-Agent field in each request
unless specifically configured not to do so.

「送信者は、生成される製品識別子を必要なものだけに制限すべき。
送信者は、製品に含まれる広告やその他の非本質的な情報
の識別子を生成してはならない。

バージョン識別子ではない(つまり、連続した
同じ製品名のバージョンは、以下の点だけが異なる必要があります。
製品識別子の製品バージョン部分)product-version は、生成すべきでない。」

A sender SHOULD limit generated product identifiers to what is
necessary to identify the product; a sender MUST NOT generate
advertising or other nonessential information within the product
identifier. A sender SHOULD NOT generate information in
product-version that is not a version identifier (i.e., successive
versions of the same product name ought to differ only in the
product-version portion of the product identifier).

https://datatracker.ietf.org/doc/html/rfc7231#section-5.5.3

kamimikamimi

User Agentを用いた処理

  • User-Agentを用いたブラウザの判別

ユーザーエージェントを調べるのが良いことはめったにありません。問題を解決するには、もっと良い、もっと広く互換性のある方法が見つかるはずです。

  • 例えば、モバイル端末かどうかを判別したい場合

要するに、モバイル端末を検出するには、ユーザーエージェント文字列のどこかに文字列 “Mobi” があるかどうかを探すことをお勧めします

  • ただし、その理由がタッチ可能な端末かどうかであれば、以下を使用すべき

Navigator.maxTouchPoints を使用しましょう。

https://developer.mozilla.org/ja/docs/Web/HTTP/Browser_detection_using_the_user_agent

kamimikamimi

User-Agentの固定化とUser Agent Client Hints の使用

  • Chromeでは、User-Agentの文字列を固定化することで、この文字列の使用することをなくそうとしている

  • 理由は以下の通り

    • HTTP リクエストのたびに、ブラウザに関する多くの情報が何もしなくても公開されること
    • 時間とともに長く複雑になり、エラーが起こりやすい文字列の解析が必要になること

https://developers-jp.googleblog.com/2021/06/chrome-user-agent.html

https://ics.media/entry/200729/

kamimikamimi

iOSアプリにおけるUser-Agent

https://dev.classmethod.jp/articles/user-agent-best-practice/

  • 自分で実験してみたところ、以下の通り

iOSアプリからのリクエストの場合

'user-agent': 'ReadingAndDeletingCookies/1 CFNetwork/1312 Darwin/20.5.0',

iOSアプリ内ブラウザ(WKWebView)

'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',

  • その他のアプリからのリクエストに含まれるUser-Agent

http://yebisupress.dac.co.jp/2015/09/01/charlesを使ってスマホアプリiosのuaを調べてみた/

https://zenn.dev/kecy/articles/f51851e42c4243

WKWebViewのUser-Agentの設定方法

  • 方法はいくつかある(SwiftUIにおいて使うのは太字のものだけではないか)
    • UserDefaultsにセットする
    • WKWebViewのカスタムUAにセットする
    • デフォルトのUAの後ろにカスタム文字列を付ける
    • Interface Builderで設定する

WKWebViewのカスタムUAにセットする

WebView.swift
webView.customUserAgent = "ProvidingACustomUserAgent"

User-Agentはこうなる

'user-agent': 'ProvidingACustomUserAgent'

デフォルトのUAの後ろにカスタム文字列を付ける

WebView.swift
let config = WKWebViewConfiguration()
config.applicationNameForUserAgent = "ProvidingACustomUserAgent"
let webView = WKWebView(frame: .zero, configuration: config)

User-Agentはこうなる

'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) ProvidingACustomUserAgent'

User-Agentの設定をWKWebViewで何もしなかった場合

'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148'

デフォルトのUAの後ろにカスタム文字列を付ける方法

https://sussan-po.com/2019/11/22/wkwebview-user-agent/

https://blog.anzfactory.xyz/articles/20190902/swift-wkwebview-custom-useragent/

kamimikamimi

WAFとUser-Agent

  • WAF側の設定でUser-Agent文字列で、アクセス制御を行う場合もある

  • そもそもWAFとは

WAF(Web アプリケーションファイアウォール)とは、Web アプリケーションの通信をフィルター、監視、ブロックするためのソフトウェアまたは、ハードウェアのセキュリティ対策

https://aws.amazon.com/jp/waf/what-is-waf/

  • AWS WAFにおける、User-Agent文字列のルール設定

https://aws.amazon.com/jp/premiumsupport/knowledge-center/waf-block-http-requests-no-user-agent/