サーバーサイドテンプレートインジェクションの仕組み(舞台裏)
サーバーサイドテンプレートインジェクションは、ユーザー入力がテンプレートエンジンに直接埋め込まれ、適切なサニタイズや分離なしに評価される場合に発生します。これにより、攻撃者が特別に細工された SSTI ペイロード (たとえば、 {{7*7}} Jinja2 の場合)エンジンが評価するこのペイロードは、サーバーコンテキストでのデータ漏洩から任意のコード実行まで、あらゆる事態を引き起こします。テンプレートエンジンによって公開されるオブジェクトや API が異なるため、SSTI ペイロードはプラットフォームごとに異なりますが、同じ危険性を共有しています。つまり、信頼できない入力が想定されるレンダリング フローから漏れ出し、アプリケーションのランタイムで実行されるため、放置すると多くの場合、完全なリモート コード実行や横方向の移動につながります。
Jinja2における最小限の脆弱性例
from flask import request, render_template_string @app.route("/hello") def hello(): name = request.args.get("name", "world") # ❌ Vulnerable: directly rendering user input return render_template_string("Hello " + name) ユーザーが送信した場合 ?name={{7*7}}アプリはそれを評価し、 こんにちは49それはまさに典型的なSSTIの脆弱性だ。
Twigにおける最小限の脆弱性例
// ❌ Vulnerable Twig usage $template = $twig->createTemplate("Welcome " . $_GET['user']); echo $template->render([]); 攻撃者は次のようなSSTIペイロードを注入できます。 {{7*7}} コード実行を証明するため。 危険性:単純なインジェクション攻撃が、ファイルの読み取り、OSコマンドの実行、あるいはインフラストラクチャへのより深い侵入へとエスカレートする可能性がある。
実際の攻撃事例:リモートコード実行を引き起こすSSTIペイロード
SSTIの脆弱性が発見されると、攻撃者は概念実証の数学から本格的な攻撃へと移行しようとします。 RCEテンプレートエンジンによってペイロードの処理方法は異なります。
Jinja2ペイロード
- {{7*7}} → 算術演算
- {{config.items()}} → サーバー設定を漏洩します。
- {{ ”.__class__.__mro__[2].__subclasses__() }} → RCEへの道
速度ペイロード
- #set($x=”7″)${x} → 噴射バイパス
- #set($a=$class.inspect(“java.lang.Runtime”)) → 直接ランタイムアクセス
枝状ペイロード
- {{7*7}} → 算術
- {{app.request.server.all}} → 環境変数
- {{_self.env.registerUndefinedFilterCallback(‘system’)}} → コード実行
これらのSSTIペイロードは、異なるエンジンにおける同じ脆弱性が、どのように異なる結果をもたらすかを示しています。 悪用経路、 しかし、それらは常に危険である。
サーバーサイドテンプレートインジェクションが隠れている場所 CI/CD-駆動型アプリケーション
サーバーサイドテンプレートインジェクションは、Webアプリのリスクに限ったものではありません。 現代の CI/CD pipelines のためにペンを持つ時間も見つけています。 典型的な隠れ場所としては以下のようなものがある。
- Helm チャート Kubernetesでは、テンプレートの値は動的にレンダリングされます。
- メールテンプレート ユーザーが制御する入力を連結する
- Dashboards クエリ文字列または設定データがテンプレートに挿入される場所
- DevOpsスクリプト テンプレートエンジンを使用してHTML/Markdownを生成するもの。
例:
# ❌ Insecure Helm values with user input configMap: appMessage: "{{ .Values.message }}" If.Values.message 信頼できない入力から来るため、デプロイメントにサーバーサイドのテンプレートインジェクションが導入されます。 pipeline そのもの。
より安全なテンプレートパターンと静的解析によるSSTIの予防
SSTIの脆弱性を軽減するには、より優れたコーディングパターンと早期発見が必要です。
安全なパターン
- ❌ 使用しないでください render_template_string または同等の
- ✅ 定義済みのテンプレートファイルを使用し、サニタイズされた変数を渡す
- ✅ 利用可能な場合はサンドボックステンプレートエンジン
- ✅ レンダリング前にユーザー入力を検証およびエスケープする
安全でないクッキー処理と安全なクッキー処理(関連する入力リスク)
# ❌ Insecure: session cookie without flags response.set_cookie("session", token) # ✅ Secure: session cookie hardened response.set_cookie("session", token, httponly=True, secure=True, samesite="Strict") 開発者向けミニチェックリスト
- ユーザー入力を直接レンダリングしてはいけません。
- サポートされている場合はサンドボックス化されたテンプレートを使用する
- すべてのテンプレート変数をサニタイズして検証する
- カスタムテンプレート評価ツールは避けてください。
- スキャンコード render_template_string または文字列連結パターン
静的解析 また、リンターは、危険な構造が本番環境に到達する前にそれを検出することができます。
DevSecOpsにSSTIチェックを組み込む Pipelines
サーバーサイドのテンプレートインジェクションを早期に発見することは、後で修正するよりも安価で安全です。DevSecOps チームは、チェックを組み込む必要があります。 pipelines:
- Commit hooks: 拒否する commit危険な機能を持つもの(render_template_string)
- 静的アナライザーテンプレートコードにおけるサーバーサイドテンプレートインジェクションのリスクをスキャンする
- 依存関係の検証既知のSSTI脆弱性を持つ古いテンプレートエンジンにフラグを立てる
- Pipeline ゲート: SSTIチェックに合格するまでマージをブロックします
SSTIペイロード検出を CI/CDそうすれば、悪用可能なコードが出荷されるのを完全に防ぐことができます。
サーバーサイドテンプレートインジェクションがスタックに紛れ込まないように
サーバー側のテンプレートインジェクション1つで、数学トリックからエスカレートする可能性があります({{7*7}})から完全なリモートコード実行まで。SSTIの脆弱性はWebアプリケーションだけでなく、 CI/CD pipelines、Helmチャート、およびメールテンプレート。
主要な取り組み
- 生のユーザー入力をテンプレートにレンダリングしてはいけません。
- すべての動的変数を検証し、サニタイズする
- 異なるエンジン(Jinja2、Velocity、Twig)はそれぞれ異なるSSTIペイロードを搭載しているが、いずれも武装化可能である。
- 静的解析とフェイルファストゲートを使用する pipelines
- スタック内の監査テンプレートを定期的にチェックする
のようなツール ザイゲニ チームが安全でないテンプレートの使用を検出し、SSI の脆弱性をブロックし、安全な慣行を徹底できるように支援します。 pipeline依存関係。 DevSecOpsでは、SSTIペイロードを最上位のリスクとして扱うことが不可欠です。なぜなら、 pipeline またはアプリがあなたの環境全体を危険にさらす可能性があります。






