Web開発
自身のJavaScriptを実行するHTMLをホストするのは安全か?
Is It Safe to Host HTML That Runs Its Own JavaScript? (sharemypage.app)
要約
ShareMyPageは、ユーザーがアップロードしたHTMLとJavaScriptをそのままホストしていますが、これはセキュリティ上のリスクを伴います。同社は、HTMLをサニタイズするのではなく、サンドボックス化されたiframe内で、オリジンを持たない(null origin)環境でページを実行するというアプローチを採用しています。これにより、スクリプトが実行されても、ユーザーのセッション情報や他のオリジンにアクセスできないように設計されています。
全文翻訳
ShareMyPageを評価している人が、私たちが受ける最も鋭い質問をしました。あなたはユーザーがアップロードしたHTMLを、JavaScriptを含めてホストしていますが、そのコードが何かを注入したり、スクリプトの一部でセッションをハイジャックしたりするのを防ぐものは何でしょうか?それはまさに尋ねるべき質問です。任意のHTMLをホストすることが製品そのものであり、そのHTMLの多くはAIによって生成され、誰も一行ずつ読む前に貼り付けられています。ですから、正直な答えは「きれいにクリーニングする」ではありません。それは、すべてのページが敵対的であると仮定し、その仮定を無意味にするということです。
なぜHTMLをサニタイズしないのか
明白な本能は、危険なものをすべてアップロードから削除することです。私たちは意図的にそうしません。理由は2つあります。第一に、それは製品を壊してしまうからです。ここで共有されるページは実際のページです。データを取得してグラフ化するダッシュボード、クリックして操作できるプロトタイプ、小さなインタラクティブツールなどです。JavaScriptが肝心なのです。それを削除すると、スクリーンショットだけが残ります。第二に、信頼できないHTMLをサニタイズすることは永続的な軍拡競争であり、防御側は1つのケースを見逃した日に敗北します。安全性がすべての危険な構造を捉えることに依存する瞬間、1つのギャップは侵害です。そこで私たちは反対のアプローチを取りました。ページをそのまま実行しますが、それがあなた、私たち、またはそれを開く他の誰にも害を及ぼすことのできない場所で実行します。それがトリックのすべてです。HTMLを安全にしようとするのではなく、それが実行される場所を安全にします。ファイル自体に信頼する必要のあるものは何もありません。
すべてのページはオリジンを持たないサンドボックスで実行されます
共有されるページは、サイト上で直接レンダリングされることは決してありません。それはサンドボックス化されたiframe内でロードされ、サンドボックスはそれが実際のページであるために必要な最小限の権限のみを付与し、誰かに到達することを可能にするものは何も与えません。
<iframe src="{コンテンツオリジン上の短命な署名付きURL}" sandbox="allow-scripts allow-popups allow-forms allow-downloads allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation" referrerpolicy="no-referrer" ></iframe>
そのサンドボックスリストから欠けているものの方が、含まれているものよりも重要です。そこにはallow-same-originがありません。その単一の省略により、フレーム化されたドキュメントは不透明なnullオリジンを持ちます。そのスクリプトは依然として実行され、チャートはアニメーションし、フォームは送信されますが、document.cookieは空で返され、localStorageは利用できず、それをフレーム化したページを読み取ったり到達したりすることはできません。それはライブページですが、どのオリジンにも属していません。
最後の2つのエントリ、allow-popups-to-escape-sandboxとallow-top-navigation-by-user-activationは、異なる種類の権限です。それらは、ユーザーのクリックが外部世界に到達することを許可し、「電話を予約する」リンクやmailtoがサイレントに失敗するのではなく開かれるようにします。それらは実際のユーザー操作に限定されており、ナビゲーションのみを制御し、データは制御しません。上記すべて(Cookie、ストレージ、オリジン)は変更されていません。
決して破らない1つのルール。allow-scriptsとallow-same-originは決して一緒に現れてはなりません。これらが組み合わさると、フレーム化されたスクリプトに実際のオリジンが戻され、保護全体が静かに無効になります。この2つを分離しておくことが、負荷を支える線です。
ページは別の、Cookieを持たないオリジンで動作します
サンドボックスは最初のレイヤーです。2番目はコンテンツが提供される場所です。HTMLは、あなたがログインするアプリから来るのではありません。それは別のオリジンから、短命な署名付きURL経由で提供され、そのオリジンはCookieを設定したり読み取ったりしません。あなたのログインセッションはアプリのオリジンにあります。それはコンテンツオリジンには存在しません。したがって、スクリプトが何らかの方法でサンドボックスを脱出したという仮説的な状況であっても、そのオリジンには盗むべきものはありません。セッションCookie、トークン、ログイン中のものなど、何もありません。私たちのコードにあるコメントはそれを平明に述べています。「サンドボックスの脱出でさえ、盗むものを見つけられない」と。
また、そのコンテンツをフレーム化できるのは私たちのアプリだけに制限しているので、ページを抜き出して、別の場所で説得力のあるフレームを装うために再利用することはできません。
したがって、直接の注入とセッションハイジャック
それらは元の質問にあった2つの言葉です。注入、クロスサイトスクリプティング(XSS)で通常意味されるバグは、あなたの信頼できるCookieを持つオリジン内で実行される信頼できないHTMLであり、それはDOMとあなたの属するCookieを読み取ることができます。ShareMyPageでは、信頼できないHTMLは決してそのオリジンに触れません。注入する信頼できるコンテキストがありません。それは検査ではなく、構築によって隔離されています。
JavaScriptによるセッションハイジャックは、セッションCookieまたはトークンを読み取り、それを再生することによって機能します。私たちのサンドボックスでは、スクリプトはnullオリジンを持つため、Cookieとストレージへのアクセスは開始前に失われます。そして、それが実行されるオリジンには、そもそもセッションがありません。攻撃が何も掴めない2つの独立した理由です。
懸念事項 | なぜそれが機能しないのか
スクリプト注入(XSS) | アップロードされたページはアプリオリジンで実行されないため、注入する信頼できるDOMやCookieがありません。
JS経由のセッションハイジャック | nullオリジンサンドボックスはCookieとストレージへのアクセスをブロックし、コンテンツオリジンにはそもそも攻撃するセッションがありません。
レイヤー化されているため、単一のロックは負荷を支えません
良いセキュリティは、1つの巧妙な制御に依存しません。それは独立したものをいくつか積み重ねるので、単一の障害が発生しても他のものが残ります。ページはnullオリジンサンドボックスで実行されるため、スクリプトはCookie、ストレージ、親への到達権を持ちません。それは別のCookieを持たないオリジンから提供されるため、そもそも攻撃するセッションがありません。それは短命な署名付きURLでロードされ、推測可能なパスではありません。そして、それをフレーム化することは私たちのアプリに限定されています。あなたがログインするアプリは独自の厳格なコンテンツセキュリティポリシーを持っているため、シェル自体をフレーム化したり注入したりすることはできません。すべての読み取りはサーバーで承認され、あなたのワークスペースにスコープされているため、漏洩したリンクでもあなたが見ることを許可されていなかったページを開くことはできません。ページはEUのプライベートで暗号化されたファイルとして保存され、パブリックバケットにはなりません。これらのうちの1つを無効にしても、残りは依然として有効です。これが、セキュリティは機能ではなく、後から追加されたものではなく、設計であると言う意味です。
主張しないこと
分離は、ページからあなたを保護し、ページから私たちを保護します。それはページの作成者をあなたが信頼すべき人物に変えるものではありません。公開リンクは依然として公開リンクです。インターネット上のどのホストでもそうであるように、人はそれを使って誤解を招くコンテンツを掲載することができます。それはモデレーションの問題であり、同一オリジン(same-origin)の問題ではなく、あなたが最も重要な部分、つまり各ページを誰が開くことができるかを制御できます。あなただけ、あなたのチーム、パスワード、完全に公開まで。
私たちはまた、継続的に強化しています。提供されるページのコンテンツセキュリティポリシーは、今日では意図的に寛容です。なぜなら、AI生成ページは正当にフォントをロードし、APIを呼び出すからです。そしてサンドボックスが実際にリスクを封じ込めているからです。アップロードされたJavaScriptを安全に実行できるようにする封じ込め、つまりnullオリジンサンドボックスと別のCookieを持たないオリジンは、最初のページから存在しており、どこにも行きません。ご自身で確認したい場合は、ページを公開し、ブラウザの開発者ツールで開いてください。フレーム化され、別のオリジンから提供され、独自のオリジンを持たないことがわかります。または、残りの部分がどのように組み合わさっているかについての、より完全なセキュリティ概要をお読みください。