本文へスキップ

推奨設定:有効にすべきもの、触らずにおくべきもの

設定が原因だと突き止めたブロックの大半は、偽装が足りなかったからではなく、偽装しすぎたことが原因でした。このページは私たちの計測結果の要約です。使う価値のある設定、得られるものより失うもののほうが大きい設定、そしてどんな設定でも解決できない少数の問題をまとめています。

まずはここから

このページでほかに何も読まないとしても、まずはこの構成から始めてください。変えても安全な軸だけを変え、レンダリング、TLS、ブラウザのバージョンはそのままにします。

javascript
import { launch } from "clearcote";

const browser = await launch({
  lightStealth: true,        // metadata identity only — rendering, TLS and version stay real
  fingerprint: "account-42", // picks this identity's metadata bundle; keep it stable per identity
  proxy: { server: "http://gateway:8080", username: "u", password: "p" },
  geoip: true,               // timezone + languages + the address WebRTC reports follow the proxy exit
  humanize: true,            // trusted native input; navigator.webdriver stays false
});

Python でも同じ API を snake_case で使えます(light_stealth、fingerprint、geoip、humanize)。軸を追加するときは意図的に 1 つずつ、しかもホストのどの部分がそれを裏付けるのか説明できる場合に限ってください。以下の表のいくつかの行(r12 の個別制御、記録済みの人間の動きによる humanize、socks5Udp、サードパーティ Cookie とプロキシのスイッチ)は、ライセンスビルド(「GitHub で無料」または Pro)が対象です。オープンビルドではこれらは無視されます。humanize は生成した軌跡にフォールバックし、パスワード付きの SOCKS5 プロキシでは接続が拒否されます。

原則:偽装とは、ホストが裏付けなければならない主張である

検知とは、珍しい値を探すことではありません。探しているのは矛盾、つまり 1 台のマシンで同時には成り立たない 2 つのシグナルです。誰も偽装していないありふれた値は、何とも矛盾しません。裏付けのない偽装値はそれ自体が陽性のシグナルになり、しかも隠そうとした元の値よりも強いシグナルになります。

したがって、オプションを有効にする前に問うべきなのは「この値はもっともらしいか?」ではなく、「このマシンのどこに問い合わせればそれを裏付けられるか、そしてその答えは一致するか?」です。画面サイズはレンダリングサーフェスと照合されます。GPU 文字列は、その GPU が生成するピクセルと照合されます。名乗っている OS は、そのプラットフォームが解決するフォントと照合されます。ホストがその主張を裏付けられないなら、正直な値のほうが安全です。仕組みについては「検知の仕組み」を参照してください。

推奨すること

設定理由
lightStealth: trueシードから導出した整合性のある値一式を、メタデータの軸(hardwareConcurrency、deviceMemory、colorDepth、devicePixelRatio、maxTouchPoints)にだけ、ネイティブの単一値スイッチを通じて適用します。canvas、WebGL、オーディオの出力、TLS、実際のブラウザバージョンはそのままです。シードが決めるのは、少数のバンドルのうちどれをアイデンティティに割り当てるかだけで、レンダリングノイズもありません。そのため、同じマシン上のアカウントは canvas ハッシュが共通になります。スケーリングされたディスプレイや特殊なディスプレイでは、バンドルが選んだピクセル比が実際の画面と合っているかを audit で確認してください。
アイデンティティごとに安定した fingerprint シードを 1 つ同じシード ⇒ 同じアイデンティティ。アカウントを使い続ける限り、同じシードを再利用してください。リクエストごとにシードをローテーションすると、ログイン済みの 1 つのアカウントが毎回新しいマシンからアクセスしてくることになり、ローテーションしているどの値よりもはるかに目立つシグナルになります。1 台のマシン上に、canvas を共有してはならない複数のアカウントがある場合は、シード付きのペルソナを使い(lightStealth を外します)、アカウントごとに固有のレンダリングノイズが付くようにしてください。
すべての起動で geoip: trueプロキシの有無にかかわらず、タイムゾーン、言語、WebRTC が報告するアドレスが出口 IP に合わせられます(timezone と acceptLanguage を自分で設定することもできます)。どちらもない場合、SDK はニューヨークと en-US を前提にします。米国の住宅用 IP から出ているのに Europe/Amsterdam を報告していれば 1 行のチェックで見つかりますし、うっかりやってしまいやすい不一致でもあります。地域を特定できない場合は、このマシンの時計のまま起動するのではなく、GeoipError で起動を中止します。プロキシを修正するか、CLEARCOTE_GEOIP_TIMEOUT_SECONDS を引き上げてください。
humanize: true入力は、人間らしいカーソル軌跡に沿った信頼済み(trusted)のネイティブイベントとして生成されます(Pro では座標指定のクリックに記録済みの人間の動きを、それ以外では生成した軌跡を使います)。その上に独自のステップごとのイージングを重ねないでください。ウェイポイントだけを指定し、補間は humanize に任せます。自作のイージングは、通常の入力では決して生じない動きの統計を生み出します。
Chrome ブランドでは widevine: trueデフォルトのペルソナは Google Chrome として振る舞い、Google Chrome は Widevine DRM の問い合わせに応答します。CDM がないと問い合わせは拒否され、そのことはどのページからでも読み取れます。Widevine & DRM を参照してください。
埋め込みのログインやチャレンジが動かない場合は allowThirdPartyCookies: trueGoogle 依存を取り除いたベースはサードパーティ Cookie をブロックしますが、標準の Chrome はこれを許可しています。そのため、サードパーティ Cookie に依存する埋め込みのログイン、決済、チャレンジのフレームが、通常のブラウザでは起こらない形で失敗します(ライセンスビルド、152 r22 以降)。
アイデンティティごとの永続コンテキストCookie、サイトストレージ、キャッシュもアイデンティティの一部です。訪問するたびに毎回そのサイトを初めて見るマシンは、それ自体が 1 つのパターンになります。
コンテナでは Xvfb 上でヘッドフル実行ヘッドありの Chrome なら、ヘッドレスモード特有の痕跡がそもそも生じません。公式イメージはデフォルトでこの方式で動作します。
名乗る予定の OS 上で実行するCSS2 のシステムフォントキーワードに応答するのはブラウザの下にあるプラットフォームで、ページやユーザーエージェントが制御できるものではありません。そのため、ユーザーエージェントを変更してもその値は変わりません。それができない場合は、Linux のフォントバンドルを削らずにそのまま残してください(後述)。
tlsProfile は match-persona のままClientHello はペルソナが名乗る Chrome のバージョンに合わせられるため、ネットワーク層と UA が一致します。デフォルトのままで正しい設定です。このオプションの存在を知っておくべき理由は、ブランドバージョンと食い違う値に固定してしまわないためです。

避けるべきこと

ここに挙げたものはどれも一般的な注意事項ではなく、実際に問題が起きることを私たちが計測で確かめたものです。

避けるべきこと何が問題になるか
ディスプレイが一致しないホストで screen / avail* を偽装する実際のウィンドウやレンダリングサーフェスと辻褄が合わない偽の画面サイズは、最も厳しいアンチボットでは確実にブロックを招く要因になります。画面サイズが lightStealth に含まれておらず、オプトインになっているのはまさにこのためです。設定する場合は、整合性のある一式(screenWidth、screenHeight、availWidth、availHeight)をすべて設定し、avail を screen と同じ値にするのではなく、もっともらしいタスクバー分の差を残してください。ヘッドレスでは、SDK がもっともらしい画面をあらかじめ選んでくれます。
ソフトウェアでレンダリングするホストで GPU を名乗るコンテナや、WARP、SwiftShader、llvmpipe でラスタライズしているクラウド VM では、デスクトップ GPU を名乗るペルソナは、ページが読み戻せるピクセルを生成できないシリコンを名乗っていることになります。ライセンスビルド 150 r12 以降(オープンビルドでは無視されます)、gpuStringSpoof: false を使うと、ほかはすべてそのままで、ホストの実際の WebGL ベンダーとレンダラーを報告します。そうしたハードウェアでは、多くの場合こちらのほうが得策です。ただし注意点があります。WebGPU は引き続き範囲の広い disableGpuFingerprint に従うため、この個別スイッチだけでは、WebGL が実際のデバイスを報告する一方で、navigator.gpu はペルソナを表したままになります。
1 つだけ変えたいのに disableGpuFingerprint や fingerprintNoise: false を持ち出すどちらも複数の設定をまとめたものです。disableGpuFingerprint は文字列だけでなく、パラメータテーブルも、readPixels の farble も、ペルソナのフィールド抑制も変更します。fingerprintNoise: false は canvas 2D だけでなく WebGL のノイズも一緒にオフにします。ライセンスビルド 150 r12 以降は個別の制御があり、文字列だけなら gpuStringSpoof: false、canvas 2D だけなら canvasNoise: false を使えます。ただし、どちらの個別制御にも知っておくべき代償があります。gpuStringSpoof: false は WebGL の文字列を変更しますが、navigator.gpu は変更しません。そのため同じページ上で WebGL と WebGPU が別々のベンダーを名乗ることになり、スコアは良くても、中身を読めば不自然です。また、シードと併用して canvasNoise: false を使うと、アカウントごとの canvas が完全になくなります。WebGL と WebGPU を一緒に変更する、範囲の広い disableGpuFingerprint を優先してください。
セッション途中でアイデンティティをローテーションするセッション中にシード、プロキシの出口、タイムゾーンを変更すると、それまでのセッションと矛盾します。ローテーションはアイデンティティ同士の間で行い、1 つのアイデンティティの中では決して行わないでください。
フォントバンドルを取り除いた Linux で Windows ペルソナを使うLinux 版リリースにはメトリック互換のクローンフォント(Segoe UI→Selawik、Arial→Arimo、Times New Roman→Tinos など)が同梱されており、SDK が起動時に FONTCONFIG_FILE を通じて組み込みます。これを取り除いたり、<binDir>/fonts/ を削除するカスタムイメージをビルドしたりすると、ペルソナが名乗る Windows のフォントファミリーがすべて 1 つのデフォルトフォントに集約されてしまいます。これは参照データがなくても見て取れます。Windows が別々の書体として同梱している 2 つのフォントが、まったく同じ寸法で計測されるからです。
JS のステルスプラグインを上に重ねるClearcote の制御はエンジンにコンパイルされています。エンジンで実装するのは、自らの存在を露呈するレイヤーをなくすためです。制御の上にスクリプトレベルの shim を追加すれば、まさにそのレイヤーを再び持ち込むことになります。上書きされた getter は文字列化すると自身のソースコードになり、toString() を 1 回呼ぶだけでそれを読み取れます。
デスクトップ用エンジンでモバイルペルソナを無条件に使うplatform: "android" は UA、タッチ、ポインタータイプ、画面、ビューポートを変更しますが、ピクセルは依然としてデスクトップ GPU から出力され(名前はモバイル GPU のものになります)、ページの細かなジオメトリもデスクトップのままです。これはベストエフォートのペルソナです。レンダリングサーフェスは、まだ自分で解決しなければならない部分だと考えてください。

プロキシ

結果を左右する度合いは、たいていどのブラウザフラグよりもプロキシのほうが大きいのに、最もデフォルトのまま放置されがちなのもプロキシです。

  • 出口 IP を固定する。アイデンティティごとに 1 つの出口 IP を、セッションの間ずっと維持します。フローの途中で IP が変わるセッションは、フィンガープリントがどれほど良くても自己矛盾を起こします。
  • 地域をペルソナに合わせ、タイムゾーンと言語は手動で設定するのではなく、geoip: true に導出させてください。
  • 認証付きプロキシはエンジンに任せる。HTTP(S) プロキシのパスワード認証にはブラウザ自身が応答するため(ライセンスビルド 151 r19 以降、Python & Node の SDK)、ページキャッシュは有効なままで、リクエストにインターセプトの痕跡も付きません。パスワード付きの SOCKS5 も、ライセンスビルドではそのまま使えます。ユーザー名とパスワードは別々のフィールドで渡してください。transparentProxy: true(152 r22 以降)は、リクエストヘッダーと接続タイミングからプロキシの存在を隠します。
  • WebRTC のトレードオフを理解する。Chromium はメディアを HTTP プロキシや SOCKS プロキシ経由では決して送信しません。そのため何もしなければ、ピア間のトラフィックは実際の回線から出ていき、リレーに本当のアドレスを読み取られてしまいます。そこで SDK は、プロキシを経由せずに出ていく WebRTC の UDP をブロックします。オープンビルドでは geoip / webrtcIp を指定するとこのブロックが解除されますが、ライセンスビルドではブロックが維持されます。ブロックは geoip: true(または webrtcIp)と組み合わせてください。そうすれば、ページからは本物の Chrome が生成するのと同じ候補が、プロキシのアドレスを報告する形で見えます。組み合わせない場合、WebRTC は何も収集せず、ブロックされているように見えます。SOCKS5 プロキシ経由でピア接続を実際に機能させるには、socks5Udp: true を設定する(ライセンスビルド。プロバイダーが UDP リレーを許可している必要があります)か、ブラウザのプロキシを使わずにフルトンネル(WireGuard/OpenVPN)を使い、args で独自の --webrtc-ip-handling-policy を渡してください。それ以外の場合は、デフォルトのブロックポリシーのままにしてください。

設定では解決できない部分

最もよく読み取られる項目の中には、その上で動かすブラウザではなく、借りているマシンによって決まるものがあります。

項目ホストが決めること
レンダリングGPU のないホストはソフトウェアでラスタライズします。この分野の製品はどれも、描画できないハードウェアを名乗るか、ソフトウェアラスタライザーであることを認めるかのどちらかしかありません。対象サイトにとってレンダリングされたピクセルが重要なら、解決策は GPU を搭載したホストを使うこと、あるいは処理を GPU 搭載マシンに転送する Canvas ブリッジを使うことです。
フォントフォントリストは、ホストが実際に描画できるものに限られます。ライセンスビルド 150 r12 以降、正規のリストは 3,000 台の実機から導出したもので、さらにホストで使えるフォントとの共通部分を取るため、描画できないフォントがページに伝えられることはありません。Linux では SDK がブラウザに同梱されたフォントバンドルを使い、ホストにインストールされたフォントは無視します。そのため、イメージにパッケージをインストールしても、ページから見える内容は変わりません。オープンビルドのバンドルには CJK フォントが含まれていないため、中国語・日本語・韓国語のテキストはグリフが欠けた状態で表示されます。ライセンスビルドのバンドルには含まれています。Windows ではホスト自身のフォントが使われます。バンドルに含まれる Windows フォントの代替フォントによって文字幅はもっともらしくなりますが、ページは local() でフォントを名前指定して読み込むこともでき、代替フォントは本来の名前を持っていません。Linux 上の Windows ペルソナで計測したところ、Segoe UI と Georgia は計測上はインストール済みと判定されたものの、読み込むことはできませんでした。
テキストスケーラーすべてのグリフのサイズは、OS のフォントスケーラー(Windows では DirectWrite、Linux では FreeType)によって決まります。どの設定もここには届きません。フォントサイズを 0.01 px ずつ変えていくと、テキスト幅が変わるステップの割合は Windows で 99%、Linux で 66% で、Windows を名乗る Linux ホストでも 66% のままです。ページがテキストを細かく読み取るなら、名乗っている OS 上で実行してください。「ユーザーエージェントの下にあるフォントスタック」を参照してください。

思い込まずに確認する

このページの主張はすべて、ブラウザの内部から計測できます。設定済みのセッションで audit を開き、一致しないと判定された行を確認してください。これは上記の問題を見つけるのに私たちが使ったのと同じツールで、現在の構成がこれらの推奨事項のうちどれに反しているかを教えてくれます。