テンプレートインジェクション
Web アプリケーションに,利用者が入力した表示名を挨拶文に埋め込む機能があり,サーバ側でテンプレートエンジンを使って「"Hello " + 入力値」という文字列をテンプレートとして評価している。入力値によってはサーバ上で任意のコードが実行された。この脆弱性(サーバサイドテンプレートインジェクション)の対策として,最も適切なものはどれか。
- ア入力から {{ や {% などのテンプレート構文を除去するフィルタ(ブラックリスト)を適用する。
- イ出力の自動エスケープ(HTML エスケープ)を有効にすれば,挿入された式は文字列として表示され,コードは実行されない。
- ウテンプレートを評価した後の出力文字列を検査し,OS コマンドやファイルパスなどの危険な文字列を含む場合は利用者に表示しないようにする。
- エ固定のテンプレートをレンダリングし,利用者の入力はテンプレートコードとして評価せず名前付きの変数(データ)として渡す。
正解と解説を見る
正解 エ
この問題の基礎知識
- テンプレートエンジンは,固定のテンプレート(文書の雛形と埋め込まれた式)にデータを当てはめて出力を生成する。テンプレート中の式はエンジンが評価して実行する。
- サーバサイドテンプレートインジェクション(SSTI)は,利用者の入力をテンプレートの文字列に連結して評価させることで,入力中の式が評価され,エンジンの機能によってはサーバ上で任意のコードが実行される脆弱性である。
- インジェクション対策の本質はコードとデータの分離であり,SQL のプレースホルダ(パラメータ化クエリ)と同じく,入力はデータとして渡し,コードとして解釈させない。
- 出力の HTML エスケープは評価結果を表示する際の XSS 対策であり,評価中の式の実行は防げない。入力から特定の構文を取り除く拒否リスト方式のフィルタは回避されやすい。
ア入力から {{ や {% などのテンプレート構文を除去するフィルタ(ブラックリスト)を適用する。
構文はエンジンや文脈ごとに異なり,ブラックリストは回避される。テンプレート構文を取り除こうとする手法は不十分と位置付けられている。
イ出力の自動エスケープ(HTML エスケープ)を有効にすれば,挿入された式は文字列として表示され,コードは実行されない。
自動エスケープはテンプレートが出力する値に対する XSS 対策で,エンジンが既に解釈したテンプレートコードには効かない。SSTI は防げない。
ウテンプレートを評価した後の出力文字列を検査し,OS コマンドやファイルパスなどの危険な文字列を含む場合は利用者に表示しないようにする。
挿入された式はテンプレートの評価中に実行されるため,評価後の出力を検査しても,コードの実行そのものは止められない。表示の抑止は情報の漏えいを一部減らすだけで対策にならない。
エ固定のテンプレートをレンダリングし,利用者の入力はテンプレートコードとして評価せず名前付きの変数(データ)として渡す。正解
入力をテンプレートの文字列に連結せず,変数として渡せば式として評価されない。パラメータ化クエリと同様に,コードとデータを分離するのが本質的な対策である。
検証用の出典出典照合済み
OWASP Server-Side Template Injection Prevention Cheat Sheet / CWE-1336 Improper Neutralization of Special Elements Used in a Template Engine照合の根拠(5 件)
- エ(正解): 固定のテンプレートをレンダリングし,利用者の値は名前付きの変数として渡す(パラメータ化クエリと同じ考え方)
Render a fixed template and pass user values as named variables, the same way a parameterized query keeps data out of SQL.
OWASP Server-Side Template Injection Prevention Cheat Sheet · Pass untrusted input only as data(新しいタブで開きます) - 前提: 入力をテンプレート文字列に連結すると入力がテンプレートのソースになる(問題文の状況)
Untrusted data, such as request parameters, stored user content, or third-party files, is concatenated into a template string, even inside an expression like "Hello {{" + name + "}}" , or passed to a string-to-template API such as Jinja2's from_string() or Flask's render_template_string() .
OWASP Server-Side Template Injection Prevention Cheat Sheet · Introduction(新しいタブで開きます) - ア(誤り): テンプレート構文を入力から除去しようとしても,構文はエンジンや文脈で異なり拒否リストは取りこぼす
Do not try to filter template syntax out of input. Syntax differs between engines and contexts, so a denylist will miss payloads.
OWASP Server-Side Template Injection Prevention Cheat Sheet · Introduction(新しいタブで開きます) - イ(誤り): 自動エスケープは出力する値に対するもので,エンジンが解析済みのテンプレートコードには効かず SSTI を防がない
Auto-escaping helps prevent cross-site scripting in HTML output. It does not prevent SSTI, because escaping applies to the values a template prints, not to template code the engine has already parsed.
OWASP Server-Side Template Injection Prevention Cheat Sheet · Keep output escaping on(新しいタブで開きます) - ウ(誤り): 挿入された式はエンジンがテンプレートを評価する時点で実行されるので,評価後の出力を検査しても実行は止められない
Server-Side Template Injection (SSTI) happens when a server-side template engine evaluates untrusted input as template code instead of rendering it as data (Common Weakness Enumeration CWE-1336 ).
OWASP Server-Side Template Injection Prevention Cheat Sheet · Introduction(新しいタブで開きます)
出典名のチートシートは cheatsheetseries.owasp.org に実在する(ページ見出し Server-Side Template Injection Prevention Cheat Sheet)。