【さーばーさいどてんぷれーといんじぇくしょん】

サーバーサイドテンプレートインジェクション(SSTI) とは?

最終更新:
💡 穴埋めの答えが「雛形の命令」に化ける

外部入力が単なるデータではなくテンプレートの命令としてサーバー上で評価され、意図しない処理を起こす攻撃。被害の範囲はテンプレートエンジンの機能や権限、設定に左右される。

📌 このページのポイント
入力を命令に混ぜるか、値で渡すか Jinjaの例:入力 {{7*7}} 危険:入力を雛形のソースへ連結 Hello {{7*7}} 雛形として評価 Hello 49 分離:固定した雛形へ値として渡す Hello {{name}} 値:{{7*7}} Hello {{7*7}} 下段は出力を雛形として再評価しない場合
式の評価とデータとしての差し込みを比較。49という結果だけでOSの命令実行まで証明されるわけではない。
ひよこ ひよこ
ペンギン先生、SSTIってどこに入り込む攻撃なの?
ペンギン先生 ペンギン先生
ページなどを作る雛形、つまりテンプレートに入り込む攻撃だよ。本来は名前などのデータとして扱う入力を、サーバーが雛形の命令として読んでしまうんだ。穴埋めの答えを書くつもりが、問題文そのものを書き換えられるような状態だね。
ひよこ ひよこ
名前を表示するだけでも起きるの?
ペンギン先生 ペンギン先生
作り方によるよ。Jinjaの例で、入力の「{{7*7}}」を「Hello 」と連結してからテンプレートとして処理すると、「Hello 49」になる。一方、固定した雛形「Hello {{name}}」へ同じ入力をnameの値として渡すだけなら、「Hello {{7*7}}」という文字列になり、その値をもう一度テンプレートとして処理しない限り計算されないんだ。
ひよこ ひよこ
49が出たら、サーバーを全部乗っ取られたってことなの?
ペンギン先生 ペンギン先生
この例で示すのは、入力の式がサーバー側で評価されたことだよ。それだけでOSの命令まで実行できるとは限らない。使える機能や渡したオブジェクト、実行権限などによって、情報漏えいやリモートコード実行につながる場合があるんだ。
ひよこ ひよこ
XSSを防ぐためのHTMLエスケープをすれば大丈夫なの?
ペンギン先生 ペンギン先生
それだけでは防げないよ。HTMLエスケープはブラウザへ出す文字の扱いを整えるもので、サーバーがテンプレートの命令を解釈する問題とは別なんだ。固定した雛形と入力データを分け、入力を雛形のソースへ連結したり、出力を再び雛形として読ませたりしないことが基本だよ。
もっと詳しく知りたい人へ

利用者が雛形を編集する機能には、サンドボックスを使えば十分?

サンドボックスだけで完全に安全にはなりません。Jinjaの公式資料は、参照できる属性や呼び出せる機能の制限に加え、CPU・メモリなどの資源制限と例外処理を求めています。雛形へ渡すデータも必要なものに絞り、副作用のあるメソッドを持つオブジェクトや不要な機密情報を渡さない設計が必要です。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「SSTI」って出てきたら「入力がサーバー上で雛形の命令として動いてしまう攻撃」と思えばだいたいOK!
📖 おまけ:英語の意味
「Server-Side Template Injection」 = サーバー側のテンプレートへの注入
💬 templateは「雛形」、injectionは「注入」で、サーバーが読む雛形に意図しない命令を混ぜるという意味だよ。

参考資料

← 用語集にもどる