サブリソースの整合性を理解する
公開: 2022-03-10 CDNでホストされているバージョンのJavaScriptライブラリを使用したことがある場合は、スクリプトタグに奇妙な外観のintegrity
属性があることに気付いたかもしれません。 この属性には、よりクリーンなコードを求めて削除したくなるような、一見無限の英数字のジャンクが含まれています。
そのすべてのがらくたは、実際にはサブリソースインテグリティ(SRI)と呼ばれる本当に便利なセキュリティ機能であり、特定の種類のハッキングや侵害からサイトを守るのに役立ちます。 この記事では、SRIとは何か、SRIがどのように保護に役立つか、CDNでホストされているファイルだけでなく、独自のプロジェクトでSRIを使用し始める方法について説明します。
ちょっとした歴史
JavaScriptがHTMLやCSSのいとこであった時代にさかのぼると、スクリプトをWebサイトの攻撃ベクトルとしてどのように使用できるかについてあまり考える必要はありませんでした。 ほとんどのサイトはすべて、独自のホスティングインフラストラクチャ上のどこかにある単一の物理サーバーでホストされていました。これは、セキュリティのベストプラクティスに関して防御することを考えたサーバーでした。
ブラウザの機能が向上し、ネット接続が太くなるにつれて、JavaScriptの使用が増え、最終的には再利用可能なJavaScriptライブラリが登場し始めました。 それらの初期の頃、script.aculo.us、Prototype、そして最終的にはjQueryのようなライブラリは、ページに双方向性を追加しようとしている開発者の間で採用され始めました。
これらの追加されたライブラリとそれに続くプラグインにより、ページの重みが追加され、やがてフロントエンドのパフォーマンスについて真剣に考え始めました。 以前は巨大企業の予備であったコンテンツ配信ネットワーク(CDN)のようなリソースは、日常の人々がきびきびとしたWebサイトを構築するために一般的になりつつありました。
途中で、一部の明るい火花は、サイトがすべて共通のライブラリの独自のコピー(最新のjQueryなど)を要求していることに気付きました。すべてのサイトで使用できるそれらのライブラリの共通のCDNバージョンがある場合、ユーザーはそうしませんでした。同じファイルをダウンロードし続ける必要があります。 彼らは最初のサイトがファイルを使用するためにヒットしましたが、それからそれは彼らのローカルブラウザキャッシュに置かれ、ダウンロードは後続のサイトごとにスキップされる可能性があります。 天才!
これが、 jsdelivr.com
などのURLを使用してお気に入りのライブラリへのCDNリンクが表示される理由です。これらのライブラリは、共通のCDNを使用してファイルをホストしているため、ユーザーはパフォーマンスのメリットを確認できます。
何がうまくいかないのでしょうか?
これは依然として優れた実用的な作業方法ですが、攻撃の潜在的なベクトルをもたらします。 2012年で、誰もが新しいjQuery1.8を使用していると想像してみてください。 従来のやり方に戻ると、誰もが自分のサーバー上の自分のWebサイトの一部として自分のjQuery1.8ファイルをホストすることになります。
ある種のjQueryベースのハンバーグラーのようなある種の邪悪なアクターであり、自分の邪悪な利益のためにライブラリをハッキングする卑劣な方法を考え出した場合、すべてのWebサイトを個別にターゲットにして、サーバーを危険にさらす必要があります。影響。 それは大変な努力です。
しかし、誰もが共通のCDNからロードされたjQueryを使用しているため、現在はそうではありません。 そして、私がみんなと言うとき、私は何百ものウェブページを意味するのではありません。 私は何百万ものウェブページを意味します。 突然、その1つのファイルが私たちの怪しげなハッカーにとって非常に魅力的なターゲットになりました。 その1つのファイルを危険にさらすことができれば、世界中の何百万ものWebページでコードをすばやく実行できます。
そのコードが何であるかは関係ありません。 ページを改ざんするのはいたずらかもしれませんし、パスワードを盗むためのコードかもしれませんし、暗号通貨をマイニングするためのコードかもしれません。 重要なことは、開発者がページに追加した無実のファイルが変更され、サイトの一部として悪意のあるJavaScriptが実行されていることです。 それは大きな問題です。
サブリソースの整合性を入力してください
SRIは、クロックをロールバックしてコードを使用するための便利な方法を放棄するのではなく、単純なレベルのセキュリティを追加するソリューションです。 SRIとintegrity
属性が行うことは、ページにリンクしたファイルが変更されないようにすることです。 そして、それが変更された場合、ブラウザはそれを拒否します。
コードが変更されていないことを確認することは、コンピュータサイエンスでは非常に古い問題であり、ありがたいことに、いくつかの非常に確立されたソリューションがあります。 SRIは、最も単純なファイルハッシュを採用するのに適しています。
ファイルハッシュは、ファイルを取得し、ハッシュまたはチェックサムと呼ばれる短い文字列表現に変換するアルゴリズムを実行するプロセスです。 雑草に入ることなく、プロセスは反復可能または可逆的であるため、他の誰かにハッシュと一緒にファイルを渡した場合、同じアルゴリズムを実行して2つが一致することを確認できます。 ファイルが変更されたり、ハッシュが変更されたりした場合、一致するものはなくなり、何かが間違っていることがわかっているので、ファイルを信用しないはずです。
SRIを使用する場合、Webページはハッシュを保持し、サーバー(CDNまたは任意の場所)はファイルを保持します。 ブラウザはファイルをダウンロードし、すぐに計算して、それがintegrity
属性のハッシュと一致することを確認します。 一致する場合はファイルが使用され、一致しない場合はブロックされます。
試してみる
今日getbootstrap.com
にアクセスしてBootstrapのバージョンへのCDNリンクを取得すると、次のようなタグが与えられます。
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
src
属性は以前と同じであり、 integrity
属性は現在ハッシュであることがわかっているものを保持していることがわかります。
ハッシュは実際には2つの部分に分かれています。 1つ目は、使用するハッシュアルゴリズムを宣言するプレフィックスです。 この場合、 sha384
です。 この後にダッシュが続き、次にbase64
でエンコードされたハッシュ自体が続きます。
画像などのインラインファイルをページにエンコードする方法として、 base64
に精通している場合があります。 これは暗号化プロセスではありません。ASCIIに適切に変換される方法で、潜在的に乱雑なデータをエンコードするための高速で便利な方法です。 これが、Webで多く使用されている理由です。
これを見ると、ブラウザはbootstrap.min.js
をダウンロードします。 実行する前に、ハッシュをbase64
でデコードし、 sha384
ハッシュアルゴリズムを使用して、ハッシュがダウンロードしたばかりのファイルと一致することを確認します。 一致する場合、ファイルが実行されます。
このタグをページに配置し、ブラウザツールの[ネットワーク]タブに移動して、ファイルが読み込まれていることを確認することで、これをテストできます。
bootstrap.min.js
(および必要なjQueryファイル)が正常に読み込まれたことがわかります。
ハッシュを更新して、間違っていることがわかっているものにするとどうなるか見てみましょう。
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-SmashingMagazineIsCoolForCats" crossorigin="anonymous"></script>
ご覧のとおり、私のページで指定されたハッシュはファイルと一致しなくなったため、ファイルはブロックされます。
独自のプロジェクトでのSRIの使用
CDN上のライブラリにこの機能があることは素晴らしいことであり、 integrity
属性を持つ埋め込みファイルを使用するオプションが表示された場合は、そのオプションを確実に優先する必要があります。 ただし、CDNの大きなプロジェクトに限定されるものではなく、自分で自分のサイトに使用することもできます。
ハッカーがサイト上のほんの数個のファイルにアクセスすることに成功したシナリオを想像するのは、まったく難しいことではありません。 私たちのほとんどは、ある時点でWordPressサイトが、そこにあることにさえ気づかなかった大量の厄介ながらくたで侵害されたクライアント、同僚、または友人を見たことがあると思います。
SRIはこれからもあなたを守ることができます。 独自のファイルに対して整合性ハッシュを生成する場合は、リモートでホストされているファイルの場合と同じように、サイトで変更を拒否することができます。
ハッシュの生成
ご想像のとおり、コンピューターの端末でいくつかのコマンドを実行して、ファイルのハッシュを生成できます。 これを行う方法のこの例は、MDNサブリソースの整合性ページからのものです。
cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A
これは、 FILENAME.js
のコンテンツを取得し、それを入力としてopenssl
に渡して、 sha384
を使用してダイジェストを作成します。これは、入力として別のopenssl
コマンドに渡され、結果をbase64
でエンコードします。 これは複雑でわかりにくいだけでなく、JavaScriptファイルが変更されるたびに手作業でやりたいことでもありません。
さらに便利なことに、これを何らかの方法でサイトのビルドプロセスに統合する必要があります。ご想像のとおり、そこには既成のオプションがたくさんあります。 正確な実装はプロジェクトによって大きく異なりますが、ここにいくつかの構成要素があります。
Gulpを使用してサイトを構築する場合は、ファイルとそのハッシュのリストを含むJSONファイルを出力するgulp-sriがあります。 その後、これをサイトで利用できます。 たとえば、動的にレンダリングされたサイトの場合、そのファイルを読み取り、必要に応じてハッシュをテンプレートに追加するためのテンプレートプラグインを作成できます。
まだGulpを使用しているが、静的サイト(または静的に生成されたサイト)がある場合は、実際にHTMLページを実行し、必要に応じてハッシュを追加するようにページを変更するgulp-sri-hashを使用できます。これは非常に便利です。
Webpackを使用している場合は、webpage-subresource-integrityがあります。これは、実際のWebpackスタイルでは、人間が予想するよりも複雑ですが、機能しているように見えます。
ハンドルバーテンプレートエンジンを使用している場合は、利用できるオプションがあるようです。ビルドプロセスが基本的なJavaScriptである場合は、そこにも簡単な解決策があります。
WordPressのようなCMSを使用している場合、私自身は試していませんが、簡単に見えるプラグインを見つけました。 SRIまたはSubResource Integrityを使用して選択した独自のプラットフォームをグーグルで検索すると、正しい方向を示す可能性があります。
基本的に、JavaScriptファイルが縮小された後でハッシュをフックし、システムのどの部分でも<script>
タグを出力するために何らかの方法でそのハッシュを利用できるようにする必要があります。 Webプラットフォームの驚異の1つは、技術的に非常に多様であるということですが、残念ながら、適切な実装手順を提供できません。
その他の注意事項
この記事では、JavaScriptファイルについて多くのことを話しました。これは、JavaScriptファイルがハッキング攻撃から防御するのに最も理にかなっている場所だからです。 SRIはCSSでも動作するため、CSSでもまったく同じように使用できます。 悪意のあるCSSのリスクははるかに低いですが、サイトを改ざんする可能性は依然として存在し、どのブラウザのバグがCSSによってサイトをハッカーに不注意にさらす可能性があるかを誰が知っていますか。 そのため、そこでもSRIを使用して作業しています。
もう1つの興味深いことは、コンテンツセキュリティポリシーを使用して、ページ上のすべてのスクリプト(またはスタイル)がSRIを使用する必要があり、もちろんSRIが検証する必要があることを指定することです。
Content-Security-Policy: require-sri-for script;
これは、SRIが常に使用されるようにする方法であり、複数のチームメンバーが作業するサイトで、作業方法に完全に精通している場合とそうでない場合がある場合に役立ちます。 繰り返しになりますが、これについて詳しく読むには、サブリソースの整合性に関する常に優れたMDNドキュメントがあります。
最後に話す価値があるのは、SRIのブラウザーサポートです。 最新のブラウザでのサポートは幅広く、主な例外はInternetExplorerです。 ただし、仕様の実装方法には下位互換性があるため、すぐに使用しても安全です。 integrity
属性を理解しているブラウザはハッシュを使用して整合性をチェックし、古いブラウザはいつものように機能し続けます。 もちろん、これらの古いブラウザでは追加の保護は得られませんが、サポートを提供しているブラウザでは得られます。
結論
integrity
属性のこれらの奇妙なハッシュが何をするかだけでなく、それらを使用してWebサイトに対する特定の種類の攻撃から防御する方法を見てきました。 もちろん、あらゆる種類のエクスプロイトからサイトを守る特効薬はありませんが、SubresourceIntegrityはチェーン内で非常に便利なツールです。
多くの場合、セキュリティ上の欠陥を悪用することは、複数の小さな断片を並べることです。 Aが配置されていて、Bを発生させることができる場合、CのバグによりDが可能になります。 SRIのようなブラウザ機能は、物事をもう少し縛り付け、その連鎖を断ち切り、ハッカーが望むものを手に入れるのを防ぐ良い方法を提供します。 さらに、それをビルドプロセスまたはCMSに統合できれば、一度セットアップしてから忘れることができ、日常の不便を引き起こすことはありません。
そのため、サブリソースの整合性を真剣に検討し、可能であればサイトに実装することを強くお勧めします。