テンプレート・インジェクション(Template Injection) は、Webアプリケーションでテンプレートエンジンを使用して動的にコンテンツを生成する際に発生するセキュリティ上の脆弱性です。攻撃者が意図的に悪意あるコードをテンプレートに挿入し、サーバー側でテンプレートエンジンがそのコードを実行してしまうことで、不正な操作や機密情報の漏洩を引き起こす可能性があります。
テンプレートエンジンは、HTMLなどの出力を動的に生成するために使われることが多く、PythonのJinja2、JavaのFreemarker、PHPのTwig、JavaScriptのMustacheなど、さまざまなエンジンが存在します。テンプレート・インジェクションは、これらのエンジンが外部からの入力を処理する際に不適切なエスケープ処理が施されていると発生します。
この記事の目次
テンプレート・インジェクションの種類
テンプレート・インジェクションには、主に以下の2種類があります。
1. サーバーサイド・テンプレート・インジェクション(SSTI)
サーバーサイド・テンプレート・インジェクション(Server-Side Template Injection、SSTI) は、サーバー側で動作するテンプレートエンジンで発生する脆弱性です。攻撃者は、サーバー側のテンプレートエンジンに悪意あるコードを挿入し、サーバー上で実行されることで機密データの取得やシステム操作を行います。特に、管理者権限でテンプレートが処理される場合、サーバーやデータベース内の情報が漏洩する可能性が高まります。
2. クライアントサイド・テンプレート・インジェクション(CSTI)
クライアントサイド・テンプレート・インジェクション(Client-Side Template Injection、CSTI) は、JavaScriptなどのクライアントサイドで動作するテンプレートエンジンに対して、悪意あるコードを挿入する脆弱性です。これにより、攻撃者はユーザーのブラウザ上でスクリプトを実行し、ユーザーのセッションを盗み取ったり、個人情報を取得するなどの攻撃が可能になります。CSTIは、クロスサイトスクリプティング(XSS)の一種として分類されることもあります。
テンプレート・インジェクションの発生原因
テンプレート・インジェクションが発生する原因には、以下のようなものがあります。
- ユーザー入力の不適切な処理 テンプレートエンジンにユーザーからの入力を直接渡してしまうと、エスケープ処理が適切に行われない場合に、悪意あるコードが実行されてしまいます。
- テンプレートエンジンの脆弱性 一部のテンプレートエンジンには、システムのリソースに直接アクセスする機能があり、これを悪用するとファイルシステムや環境変数にアクセスされるリスクがあります。たとえば、Jinja2やTwigなど一部のテンプレートエンジンは、条件付きで任意のコードを評価する機能を持っています。
- テンプレートエンジンの誤った使用方法 テンプレートエンジンが提供する機能や構文を適切に理解せずに使用することで、攻撃者によるインジェクションのリスクが高まることがあります。例えば、変数のエスケープ漏れや、直接的な変数挿入などです。
テンプレート・インジェクションの攻撃例
テンプレート・インジェクションの典型的な攻撃例として、以下のようなケースが挙げられます。
サーバーサイド・テンプレート・インジェクションの例
たとえば、PythonのJinja2を用いたテンプレートがあるとします。ユーザーの名前を表示する際に、以下のようにユーザー入力がテンプレートに渡されていた場合:
このコードでは、username
にユーザーの入力がそのまま使用されており、エスケープが適切に行われていません。攻撃者がuser_input
として {{ 7*7 }}
のようなコードを入力すると、Jinja2が評価を行い、出力にHello, 49!
と表示されます。さらに、任意のPythonコードを実行することも可能で、システムコマンドが実行されるなどの深刻なリスクが発生します。
クライアントサイド・テンプレート・インジェクションの例
JavaScriptでMustacheやHandlebarsといったテンプレートエンジンが使用される場合、以下のようにユーザー入力がテンプレート内に直接組み込まれると、CSTIが発生する可能性があります。
ユーザーが{{alert('XSS')}}
のようなスクリプトをuserInput
に挿入すると、テンプレートエンジンがコードを展開し、結果としてブラウザ上で alert('XSS')
が実行され、クロスサイトスクリプティング(XSS)攻撃が成立してしまいます。
テンプレート・インジェクションの影響
テンプレート・インジェクションの成功は、以下のような深刻な影響を及ぼします。
- サーバー側の情報漏洩
サーバーサイド・テンプレート・インジェクションが発生した場合、攻撃者はファイルシステム、環境変数、データベースへのアクセスなど、システムの重要情報にアクセス可能になります。 - 任意コードの実行
特定のテンプレートエンジンを利用している場合、攻撃者がシステムコマンドを実行し、アプリケーションやサーバー全体に対して操作を行うことが可能です。 - クライアント側の個人情報漏洩
クライアントサイド・テンプレート・インジェクションにより、攻撃者がユーザーのセッションや個人情報を盗み、クライアントデバイスに対する不正な操作を行うリスクがあります。
テンプレート・インジェクションの対策
テンプレート・インジェクションを防ぐためには、次のような対策が有効です。
- テンプレートエンジンの設定を適切に行う テンプレートエンジンのオプションで、コードの自動実行や評価を禁止する設定を行うことで、エスケープ処理が確実に行われるようにします。また、テンプレートの設定を見直し、必要以上の権限を持たせないことが重要です。
- ユーザー入力のエスケープ処理 ユーザー入力をテンプレートに渡す前に、サニタイズ(無害化)やエスケープを行い、スクリプトの実行を防ぎます。たとえば、Jinja2の場合は
{{ username | e }}
のようにエスケープフィルターを使用します。 - テンプレートエンジンに直接ユーザー入力を渡さない ユーザー入力が直接テンプレートエンジンに渡されないように設計することも効果的です。テンプレートの生成や表示に必要な情報だけを変数として渡すことで、ユーザー入力が不正に処理されるリスクを低減します。
- サーバーの権限管理を強化 テンプレートエンジンが動作するアプリケーションやサーバーに対して、過剰な権限を与えないようにします。必要最低限の権限のみを設定し、万が一テンプレート・インジェクションが発生しても影響を最小限に抑えます。
まとめ
テンプレート・インジェクションは、テンプレートエンジンを利用するWebアプリケーションにおいて、外部から悪意あるコードが挿入・実行される脆弱性です。主な攻撃として、サーバーサイド・テンプレート・インジェクション(SSTI)やクライアントサイド・テンプレート・インジェクション(CSTI)があり、機密情報の漏洩や不正操作が発生する可能性があります。対策には、ユーザー入力のエスケープ処理、テンプレート設定の見直し、入力値のサニタイズなどが重要です。