何が起きるか

SSTIは、利用者が入力した文章をサーバー側のテンプレートのプログラムへ組み込み、その文章に含まれる式までサーバーで評価してしまう問題です。

説明用に、入力名を「こんにちは、」という文字列へ連結してから、{{ ... }}を式として扱うテンプレートエンジンで評価するメール作成機能を考えます。攻撃者が名前として{{ 7 * 7 }}を送ると、サーバーが作るひな形は「こんにちは、{{ 7 * 7 }}」です。エンジンが式を計算し、出力が「こんにちは、49」になれば、名前を文字として表示するはずの処理で利用者の式を動かしています。

計算できることだけで任意のコード実行を証明したことにはなりません。ただしエンジンへ公開した設定を式から参照でき、その値をメールやHTTP応答へ出力できる構成なら、攻撃者が接続パスワードなどを取得するおそれがあります。実行場所はブラウザではなく、メールやページを作るサーバーです。 たとえばアプリが描画APIへconfigというオブジェクトを渡し、そのdbPasswordプロパティをテンプレートから読めるエンジンなら、入力の{{ config.dbPassword }}もひな形へ連結されると値を出力できます。設定の公開は、アプリが描画時の参照対象として渡すことを指します。

正常ならどう動くか

サーバーは「こんにちは、{{ name }}」のような固定のひな形をプログラム側で用意し、nameへ利用者が入力した文字列をデータとして渡します。{{ ... }}を使う説明例では、エンジンが評価するのは固定ひな形にあるnameの参照で、その値の中の式は再コンパイルしません。

そのため、入力名が{{ 7 * 7 }}でも、出力は「こんにちは、{{ 7 * 7 }}」という文字列になります。利用者の値をひな形のソース文字列へ連結してからコンパイルする処理とは、エンジンが式として読み取る範囲が違います。実際の記法は使用するエンジンに従います。

不備と攻撃が成立する流れ

攻撃者が名前やメール本文の入力欄へ、テンプレートエンジンの式を含む文章を送ります。アプリがその文章をひな形の文字列へ連結し、その後でテンプレートとしてコンパイルすると、利用者の文章中の式までサーバーで評価されます。名前の値ではなく、評価するプログラムの一部へ変える処理が不備です。

{{ ... }}の記法を使うエンジンでの説明用の例です。{{ 7 * 7 }}をひな形へ連結してから評価すると、表示結果は49になります。固定ひな形のデータ変数として渡す方式なら、通常は入力した式の文字列を表示し、入力中の式を再評価しません。記法と実際の評価範囲はエンジンによります。

テンプレートへ公開した設定やオブジェクトから、ファイル読取や関数呼出へ到達できる場合は、計算式以上の処理を動かせます。単純な計算の成功と、任意の関数を呼べることは同じ証明ではありません。 ファイルを読むメソッドを持つオブジェクトを描画APIへ渡しているエンジンでは、入力した式がそのメソッドを呼べる構成もあります。何を呼べるかはアプリが渡したオブジェクトとエンジンの機能に依存し、計算式の評価だけから同じ到達性を推測しません。

起こり得る被害と条件

秘密取得の例では、攻撃者が入力した式がテンプレートへ公開された設定を参照し、メール本文やHTTPレスポンスへ接続パスワードを出力します。その出力を攻撃者が受け取れれば、秘密を入手します。設定へのアクセスと、攻撃者へ出力が届く経路が必要です。

コード実行の例では、エンジンから呼べる機能を通じ、サーバーのファイルを読む処理や外部プログラムを起動する処理へ到達します。動作範囲はアプリのOSユーザーの権限と隔離設定に従います。式を評価できるだけで、サーバーの全権限を得るわけではありません。

防ぎ方と、防げる理由

通常の名前入力では、固定ひな形へデータとして渡し、利用者の値をひな形のソースへ連結しません。これにより、入力者が評価する式の構造を変更する経路をなくせます。ひな形自体を編集できる権限は信頼する利用者に限定します。一般利用者にも式を書く機能を許す場合は別の設計として、たとえば指定した数値の計算だけを許し、設定やファイル読取オブジェクトを参照対象へ渡さない制限付きの言語を選びます。任意の式を許す汎用テンプレートをそのまま公開する方式とは区別します。

よくある誤解

HTMLエスケープはブラウザでのHTML解釈を扱う対策です。テンプレートの式が先にサーバーで実行されるなら、その問題は解決しません。ブラウザのXSSと実行場所を区別する必要があります。

実装の確認点

テンプレートのコンパイル・描画APIに渡す文字列を確認し、フォーム入力、DBに保存した文章、メール本文のどの値が連結されるか追います。ひな形を編集できる人と、テンプレートから参照できる設定・ファイル・関数も確認します。

出典・確認範囲

  1. [1] Web Security Academy: サーバーサイドテンプレートインジェクション(SSTI)PortSwigger / 確認日 2026-10-29