Content-Security-Policy が 'strict-dynamic' を使用

v3.3.0.beta1 から、Discourse は ‘strict-dynamic’ Content Security Policy (CSP) を実装します。これにより、手動での CSP 設定が不要になり、タグマネージャーや広告などの外部ツールとの互換性が大幅に向上します。

サイト管理者であるあなたは、何もする必要はありません。この変更は自動的に有効になり、使用している外部スクリプトは引き続き機能します。

テーマに変更は必要ありません。少数のプラグイン [1] では、この変更との互換性のために簡単な調整が必要になる場合があります(例:12)。

以前、外部スクリプトとの互換性のために CSP を無効にしていたフォーラムは、問題や設定の手間なく CSP を再度有効にできるようになります。

技術的な詳細については、こちらのトピックをご覧ください。

現時点では、‘content security policy strict dynamic’ サイト設定を無効にすることで、以前のシステムに戻すことが可能です。もしその理由がある場合は、お知らせください!


v3.3.0.beta3 から、‘strict-dynamic’ キーワードは CSP の必須要素となりました。‘content security policy strict dynamic’ サイト設定は削除され、‘content security policy script src’ サイト設定は有効な値のみを格納するように更新されました。

管理者の方は、以前の ‘content security policy script src’ サイト設定の値を、サイトのスタッフアクションログ(https://<サイトURL>/admin/logs/staff_action_logs?filters=%7B%22action_name%22%3A%22change_site_setting%22%2C%22action_id%22%3A3%2C%22subject%22%3A%22content_security_policy_script_src%22%7D - <サイトURL> をサイトの基本 URL に置き換えてください)から見つけることができるはずです。


  1. 技術的には、register_html_builder または erb テンプレートを介して <script> 要素を導入するものです。 ↩︎

「いいね!」 26

'unsafe-eval' を以前のように構成するにはどうすればよいですか?

「いいね!」 1

そこに変更はありません - content security script src サイト設定に 'unsafe eval' (引用符付き) を追加できます。

「いいね!」 3

content security script src の設定の説明で、content_security_policy_strict_dynamic を有効にするとこの設定が無視されると記載されていたため、確認に来ました。

「いいね!」 3

説明によると、

content_security_policy_strict_dynamic が有効になっている場合、ホストソースは無視されます。

そこでの重要な部分は「ホストソース」です。「unsafe-inline」はホストソースではないため、引き続きサポートされます。

とはいえ、これは非常に紛らわしいと私も完全に同意します。strict-dynamic のロールアウトが成功したことを考えると、古いシステムを削除する予定です。それが完了したら、すべてのホストソースをリストから自動的に削除でき、管理者ははるかにシンプルになります。:rocket:

「いいね!」 5

承知いたしました。明確化ありがとうございます。

「いいね!」 4

デビッド様

いくつか明確にしておきたい点があります。

この新しいシステムは、おそらく以下のような場合にうまく機能すると思われます。

  • インラインスクリプト
  • ローカルでホストされている完全なスクリプトソース

しかし、「loadScript」で呼び出され、完全なリモートURLが指定されているリモートスクリプトの場合はどうでしょうか?

私の認識が間違っていなければ、このケースをうまく処理する方法はないのではないでしょうか?

ということは、これらのケースでは代わりに以下に頼る必要があるということでしょうか?

  • その呼び出しをインラインスクリプトに移動する、または
  • テーマアセットとして完全なソースをダウンロードする?

前者(インラインスクリプト)の場合、スクリプトを使用する前にスクリプトがロードされることを保証する方法はないのでしょうか?(loadScriptの後の.then内でできるようなこと)

「いいね!」 2

strict-dynamicloadScript 経由で読み込まれるリモートスクリプトでも機能するはずです。実際、それが切り替えの主な理由でした。すべての外部スクリプト URL を事前にリストアップする必要がなくなりました。これは、広告を配信する人々にとって特に良いことです。広告はしばしば大量のリモートスクリプトを読み込むためです。

loadScript でエラーが発生していますか?

「いいね!」 3

エラーが発生していましたが、この理由ではないかもしれません。例を見つけさせてください。

主に、loadScriptとリモートスクリプトを含む安定したアップグレードの準備をしていました。

loadScriptを使用してコード内でランダムに呼び出されるリモートスクリプトが、どのようにしてDynamic mode CSPによって「承認」されるのか、ご説明いただけますでしょうか?何か魔法でもかかっているのでしょうか?

「いいね!」 3

はい!

MDNには、素晴らしい説明と例があります。

'strict-dynamic'ソース式は、マークアップに存在するスクリプトに、nonceまたはハッシュを付随させることによって明示的に与えられた信頼が、そのルートスクリプトによってロードされたすべてのスクリプトに伝播されることを指定します。

したがって、元のスクリプトが信頼されている(nonceを介して)限り、ブラウザは他のスクリプトを無制限にロードすることを許可します。そして、それらのスクリプトは信頼されているため、さらにロードできます!


注意点が1つあります。それは、スクリプトが「パーサー挿入」されないことです。これにより、strict-dynamicがXSS攻撃に悪用されるのを防ぎます。

たとえば、これは「パーサー挿入」され、ブロックされます。

document.head.appendChild("<script src='https://example.com/xss-attempt.js' />");

しかし、スクリプト要素をプログラムで構築することはHTML解析を伴わず、XSSベクトルである可能性がはるかに低いため、許可されます。

const script = document.createElement("script");
script.src = "https://example.com/script.js"
document.head.appendChild(script);

^^ これは基本的にloadScript()の仕組みです。

「いいね!」 3

素晴らしいリンクです。

OK、ほぼ完了しました。ありがとうございます!

nonce は loadScript によってレンダリングされるスクリプトタグにも含まれていますか?

「いいね!」 2

いいえ、ノンスはRailsによってレンダリングされた元のスクリプトタグ(コア、プラグイン、またはテーマのスクリプトなど)にのみ含まれます。

これは、コア/プラグイン/テーマコードが信頼されており、他のスクリプトを挿入することが許可されていることを意味します。ここではノンスは必要ありません。ブラウザはどのスクリプトが挿入を実行したかを知っており、信頼できることを魔法のように知っています。

「いいね!」 4

デビッド、今回もありがとうございました!

「いいね!」 4

6件の投稿が新しいトピックに分割されました: テーマコンポーネント経由でスクリプトを追加する際のCSPエラー