こんにちは、ZOZOTOWN部フロントエンドチームの高橋(@anaheim0894)です。
Chrome 92から「SharedArrayBuffer」の仕様が変更されます。それに伴い、ZOZOTOWNの対応方針と解決策をご紹介いたします。そもそも「SharedArrayBuffer」が何のことなのか分からず困っている方も多いかと思います。本記事で紹介するZOZOTOWNの取り組みが対応時に皆様の参考になれば幸いです。
取り組みのきっかけ
2021年3月、Google Search Consoleに以下メッセージが送られてきました。
Googleの公式アナウンスによると、「Chrome 92からはcross-origin isolation(クロスオリジン分離)が構成されていないと正常に動作しなくなる」と書かれていました。
つまりSharedArrayBufferを引き続き使うには、他サイトのリソースをzozo.jp内で読み込むために明示的に許可する必要があります。
現状では、Chrome以外に既にこの仕様になっているものもあります。
- Firefox
- バージョン76でこの仕様になっている
- Firefoxの最新バージョンは89(2021/06/29現在)
- Android版 Chrome
- バージョン88でこの仕様になっている
しかし、上記環境におけるZOZOTOWNの不具合報告は特に受けていません。
なお、サーチコンソールのメッセージには「Chrome 91から」と記載がありましたが、その後のGoogle Developersのアナウンスにより、対応時期が「Chrome 92(2021/07/20リリース)から」に延期されました。
SharedArrayBufferに関する詳細は「海外SEO情報ブログ」にまとまっているので、併せてご覧ください。
SharedArrayBufferの概要
SharedArrayBuffer(以下、SAB)は以下のようにまとめられる技術です。
- Webサイトのスレッド間でメモリ空間を共有するためのJavaScriptのオブジェクト
- Web Worker(バックグラウンド処理)間でメモリを共用利用するための技術
詳細は、MDN Web Docsをご覧ください。
調査・検証
調査・確認として、以下の5点を実施しました。本章ではそれぞれの内容を紹介します。
- 「SharedArrayBuffer」でソースコード全検索
- cross-origin isolation(クロスオリジン分離)の確認
- テスト環境でクロスオリジン分離状態のテスト
- ReportingObserverでSAB使用箇所を特定
- 有識者への相談
1.「SharedArrayBuffer」でソースコード全検索
「SharedArrayBuffer」という文字列でZOZOTOWNのソースコードを全検索をしました。
その結果、「ヒット無し」で使われている箇所がないことを確認できました。
2. cross-origin isolation(クロスオリジン分離)の確認
そもそも、ZOZOTOWNがクロスオリジン分離状態になっているかどうかを確認します。Chromeの検証ツールを利用し、Consoleで「self.crossOriginIsolated」を叩くことで確認できます。
その結果、「false」の表示が返ってきました。つまり、「クロスオリジン分離状態にはなっていない」と解釈できます。
3. テスト環境でクロスオリジン分離状態のテスト
前述の確認でクロスオリジン分離状態になっていないことは確認できました。そこで、テスト環境で意図的にクロスオリジン分離状態を作りました。HTTPヘッダーに以下の値を追加すると、クロスオリジン分離状態にできます。
Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Opener-Policy: same-origin
すると、zozo.jp以外からの読み込みファイルは全てブロックされた状態、具体的には画像などが全て表示されない状態になります。
同様の現象になることを防ぐには、サードパーティ側(zozo.jp以外のドメイン側)のHTTPヘッダーにCORS(Cross-Origin Resource Sharing)か、CORP(Cross-Origin-Resource-Policy)のどちらかを付与してもらう必要があります。
access-control-allow-origin: * cross-origin-resource-policy: cross-origin
このヘッダーの追加により、zozo.jp内で読み込み可能となります。
しかし、zozo.jp以外の読み込みドメインの数を確認したところ、かなりの量がありました。そのため、それぞれの企業にこのヘッダーを追加していただくのは非現実的だと判断しました。
4. ReportingObserverでSAB使用箇所を特定
サーチコンソールで「SABが使用されている」と検知されているため、使用箇所を特定する必要があります。
JavaScriptのReportingObserverを使用すると以下の情報を取得できます。
- type(レポートの種類:deprecation/intervention/crash)
- url(対象ページ)
- body(詳細情報)
- id(レポートID)
- message(Console上の警告テキスト)
- lineNumber(何行目)
- columnNumber(何列目)
- sourceFile(対象ファイル)
- anticipatedRemoval(現在のブラウザから削除されることが予想される日付)
SABの場合、Typeが「deprecation」になり、上記の項目を取得できます。なお、「intervention」や「crash」の場合、Bodyの中身で取得できる項目が異なるのでご注意ください。
SABを使用している箇所がある場合、Chromeの検証ツールで以下の警告が出ます。
[Deprecation] SharedArrayBuffer will require cross-origin isolation as of M91, around May 2021. See https://**/ for more details.
つまり、共通で呼び出されるJavaScript内にReportingを仕込めば、Warningを検知して使用箇所を特定できます。
関係する部内のチームが連携し、レポートの実装をしました。
- フロントエンドチーム
- バックエンドチーム
- フロントエンドから呼び出すエンドポイントの実装
- SREチーム
- Splunkにデータ集積
実装方法の詳細は、下記のGoogleの公式ドキュメントをご参照ください。
また、ReportingObserverを入れた状態のZOZOTOWNでレポートログを取得したところ以下の事が分かりました。
- 発生したページ
- TOP/検索結果/商品詳細/カートなど
- 対象のJavaScriptファイル
- 「chrome-extension://」から始まるJavaScript
上記の内容を含んだログが取得できました。発生したページは主要ページではあるものの規則性が無く、対象のJavaScriptファイルは全てChrome拡張機能で使用されているJavaScriptでした。
その結果、サーチコンソールで検知されたのは特定のユーザーが利用しているChrome拡張機能で使用されたJavaScriptにSABが使用されており、その警告が検知されたのではないかと予想がつきました。
5. 有識者への相談
インターネット上の情報だけでは判断・理解しきれない内容もあったので、本件に詳しい有識者の方へのヒアリングを試みました。
弊社社員の人脈から、本件に詳しい「Eiji Kitamura / えーじ」さんとつながることができました。
えーじさんはGoogleの公式ドキュメントとしてSABの取り組みを執筆されており、気になる点を相談するにはまさに理想的な方にお話を伺うことができました。
以下の内容が、えーじさんに相談することで得られた知見です。
- ファーストパーティとしてSABを利用していないことが確認できれば特に心配する必要はない
- 全ソースコードで「SharedArrayBuffer」という文字列が検索でヒットしなければ、サードパーティ製ライブラリを含め、ファーストパーティにもSABが使用されていないという判断で問題ない
- 既に仕様に組み込まれているFirefoxなどで、問題なく動いていればほぼ問題ない
- Chrome Canary(開発者向けChrome)を利用すると、Chrome 92で予定されているSABがcross-origin isolationを必須としている仕様なので、現時点でテストが可能である
- Chrome拡張機能のJavaScriptでログが取れた場合、Content Scriptにてサイトに挿入されたものであれば、サーチコンソール検知対象に含まれている可能性が高い
- サードパーティでiframeを使用している場合、その箇所はReportingObserverを使用してもログに上がってこないので実際にテストを実施する必要がある
- サーチコンソールに届いたメッセージは、このケースに該当する場合にも送られている
- React 17.0.2未満のバージョンではSABが利用されていているが、下位バージョンでのProduction buildファイルに検索して出てこないのであれば心配はいらない
- サードパーティ側のHTTPヘッダーにCORS/CORPのどちらかを付与してもらうのが難しい場合に対応するため、CORSやCORPに対応していなくてもクロスオリジンのリソースを読み込めるよう、ブラウザがCookieを取り除いて(盗まれて困る情報がない状態で)読み込むCOEPモードの追加が進められている
- COEPモードの追加が実装されるまでにSABを利用したいページがある場合は、Origin Trialに登録することで、Chrome 92以降でもこれまで通りSABを使い続けることができる
- ただし、この対応策は時限的対応なので、Chrome 96以降はcross-origin isolation対応しなければSABが使えなくなる
- Chrome 96までの予定だが、上記を含むいくつかの改善点が実装されるまでは延長される予定
ZOZOTOWNの対応内容
上記の調査・確認結果より、現状のZOZOTOWNを以下のように分析しました。
- 「SharedArrayBuffer」の文字列検索にヒットしていないため、ファーストパーティにSABは使用されていない
- Chrome拡張機能のJavaScript、もしくはサードパーティのJavaScriptでSABが使用されているのが原因でサーチコンソールに検知された可能性が高い
- Firefoxで不具合報告がないので問題ない
- Chrome Canaryでテストの実施が可能である
その上で、以下の2点を実施することで、サービスに影響が出ないという結論を出しました。
- Chrome Canaryや最新版Firefoxで、主要機能・決済までのフロー・サードパーティのJavaScript使用箇所をメインとした網羅的テストを実施する
- Reportingの実装・リリースを行い、Warningが出ている箇所を特定する
- 特定箇所が検出された場合、テストの実施と個別に対応する
- ZOZOTOWNで取得したログでは全てChrome拡張機能のJavaScriptが対象だったため、恐らくこれが原因と思われる
最後に
サーチコンソールにメッセージが届き、はじめは戸惑いました。しかし、えーじさんの協力も得ることができ、自信を持って解決策を見出すことができました。
Chromeは、今後もよりセキュアなブラウザにするためのアップデートが続いていくでしょう。その際にも、今回のような調査を行い、そこで得られた知見のアウトプットを続けていきます。
ZOZOテクノロジーズでは、一緒にサービスを作り上げてくれる仲間を募集中です。 ご興味のある方は、以下のリンクからぜひご応募ください!