【ITニュース解説】Protecting against cross-site scripting with trusted types
2025年09月24日に「Dev.to」が公開したITニュース「Protecting against cross-site scripting with trusted types」について初心者にもわかりやすく解説しています。
ITニュース概要
「Trusted Types」は、ウェブアプリのXSS攻撃対策を強化する新機能だ。HTMLやスクリプトを動的に生成する際、危険な箇所へ直接文字列を渡すのを禁止する。開発者が定義したポリシーで安全性を保証した特別な値のみを受け入れることで、DOMベースのXSSを効果的に防ぐ。
ITニュース解説
Webアプリケーションを開発する上で、ユーザーの安全を守ることは非常に重要である。インターネット上にはさまざまな脅威が存在するが、その一つに「クロスサイトスクリプティング(XSS)」という攻撃がある。これはWebサイトに悪意のあるスクリプト(プログラムコード)を埋め込み、サイトを訪れたユーザーのブラウザ上でそのスクリプトを実行させることで、個人情報の窃取やセッションの乗っ取りといった被害を引き起こす攻撃手法である。長年にわたり、Webアプリケーションで最も一般的な攻撃手法の一つとして知られている。
従来のWeb開発では、ユーザーからの入力を基に動的にHTMLコンテンツを生成したり、JavaScriptコードを実行したりする場面が頻繁に存在する。例えば、ユーザーが入力したコメントをWebページに表示する際、そのコメントがそのままHTMLとして解釈される危険性がある。JavaScriptには、innerHTML、insertAdjacentHTML、document.write、script.src、iframe.srcdocといった、文字列をHTMLやスクリプトとして解釈し、Webページに挿入する機能が多数存在する。これらは「注入シンク(injection sinks)」と呼ばれ、Webページを動的に操作するために不可欠な機能である一方で、開発者が誤って使用すると、悪意のあるコードを注入されるリスクがある。
こうしたリスクを防ぐためには、通常、これらの注入シンクに渡す文字列を「サニタイズ(無害化)」する必要がある。サニタイズとは、入力された文字列からHTMLタグやスクリプトタグなど、悪意のある可能性のある要素を取り除いたり、無効化したりする処理のことである。しかし、開発者がサニタイズ処理を忘れたり、コードの複雑な経路の中で見落としが生じたり、あるいはサードパーティ製のライブラリが適切にサニタイズを行わないといった問題が発生し、結果としてXSS脆弱性が生まれてしまうことが多かった。
このような背景から登場したのが、「Trusted Types(トラステッド・タイプス)」という新しいセキュリティ機能である。Trusted Typesは、Webブラウザの仕組みを活用して、DOM(Document Object Model)ベースのXSS攻撃を格段に難しくすることを目指している。DOMベースのXSSとは、ブラウザ上でJavaScriptが実行される際に、悪意のある文字列がDOMを操作する機能に渡されてしまうことで発生するXSSの一種である。
Trusted Typesが有効になっている環境では、ブラウザはinnerHTMLなどの危険な注入シンクに対して、「生の文字列」を直接渡すことを拒否する。代わりに、これらのシンクにはTrustedHTML、TrustedScript、TrustedScriptURLといった特別な「信頼された値」だけを受け入れるようになる。これらの信頼された値は、開発者が事前に定義した「ポリシー」を通じてのみ作成できる。
ポリシーは、入力された文字列をサニタイズしたり、検証したりする役割を担う。つまり、ポリシーの中で安全性を確認した上で、その文字列を「これは安全なHTMLである」「これは安全なスクリプトである」とブラウザに保証するための特別なオブジェクトとして変換して渡すのである。これにより、Webアプリケーションの脆弱性が大幅に減少し、攻撃者が簡単に悪意のあるコードを注入できなくなる。ただし、重要な点として、Trusted Typesが自動的に文字列をサニタイズしてくれるわけではない。開発者自身が、安全なポリシーを適切に実装する(または既存の安全なライブラリを使用する)責任がある。
Trusted Typesは、主に二つの要素が連携して機能する。一つは「Content Security Policy(CSP)」という設定であり、もう一つはブラウザのグローバルオブジェクトである「trustedTypes」である。
まずCSPについて説明する。CSPは、Webサイトが読み込むリソースの種類やソースを制限することで、セキュリティを高めるための仕組みである。Trusted Typesを有効にし、設定するには、HTTPレスポンスヘッダまたはHTMLの<meta>タグにCSPディレクティブを記述する。例えば、「Content-Security-Policy: trusted-types app dompurify; require-trusted-types-for 'script';」のような記述である。
このCSPディレクティブには二つの主要な部分がある。trusted-types app dompurifyという部分は、このWebページで作成を許可するTrusted Typesポリシーの名前をリストアップする。この例では「app」と「dompurify」という名前のポリシーが許可される。'none'を指定すればポリシーの作成を完全に禁止でき、'*'を指定すればあらゆる名前のポリシーを許可するが、これはセキュリティ上のリスクがあるため推奨されない。
もう一つのrequire-trusted-types-for 'script'という部分は、スクリプトを作成したり、HTMLを解析したりする危険な注入シンク(innerHTMLやscript.srcなど)に対して、Trusted Typesの適用を強制するものである。現在、この部分に指定できるキーワードは「'script'」のみである。Trusted Typesを本番環境に導入する前に、その影響をテストしたい場合は、「Content-Security-Policy-Report-Only」というヘッダを使用することで、実際にブロックせずに違反レポートだけを受け取ることができる。
次に、trustedTypesグローバルオブジェクトについて説明する。これはwindow.trustedTypesとしてアクセスできるオブジェクトで、これを使って開発者は自身の「ポリシー」を作成する。ポリシーは、指定された名前を持つオブジェクトであり、createHTML、createScript、createScriptURLといったメソッドを実装する。これらのメソッドは、入力された文字列を受け取り、その文字列をサニタイズしたり検証したりした後、TrustedHTMLなどの信頼された値を返す。ブラウザは、このポリシーによって作成された信頼された値であれば、危険な注入シンクに渡されても受け入れる。例えば、サニタイズライブラリであるDOMPurifyをポリシー内で利用し、createHTMLメソッドで入力文字列を安全なHTMLに変換してから返すといった使い方が可能である。
特別なケースとして、「'default'」という名前のポリシーも定義できる。Trusted Typesが強制モードの時に、もし誤って生の文字列が危険なシンクに渡された場合、ブラウザはこの「'default'」ポリシーが存在すれば、そのポリシーを通じて文字列を処理しようとする。これにより、開発者が全ての箇所で明示的にポリシーを適用していなくても、ある程度の保護を提供できる。
Trusted Typesのブラウザサポート状況は現在進行形である。現時点では、ChromeやEdgeといったChromiumベースのブラウザでネイティブにサポートされている。FirefoxやSafari/WebKitでも実装作業が進められている段階だが、まだデフォルトでは有効になっていない。しかし、ネイティブサポートが完全ではないブラウザ環境でもTrusted Typesのパターンを導入し、アプリケーションを将来の対応に備えさせるために、「ポリフィル(polyfill)」が提供されている。ポリフィルは、ブラウザがネイティブで提供していない機能をJavaScriptなどでエミュレートするもので、Trusted Typesの導入を今日から始めることができる。ただし、ポリフィルはネイティブのサポートと同等の強力な強制力を提供するわけではないが、違反を検出するのに役立つ。
このように、Trusted TypesはWebアプリケーションにおけるXSS攻撃からの保護を大幅に強化する、非常に有望な機能である。CSPによる強制ルールと、開発者が定義するポリシーという二つの要素が組み合わさることで、動的に生成されDOMに追加されるコンテンツが本当に信頼できるものかどうかが保証される。システムエンジニアを目指す上で、Webセキュリティは避けて通れない重要なテーマであり、Trusted Typesのような新しい防御策への理解を深めることは、安全なWebアプリケーション開発を行う上で不可欠な知識となるだろう。