SSTI(Server-Side Template Injection)は、サーバーサイドテンプレートインジェクションの略称で、攻撃者がWebアプリケーションのテンプレートエンジンに悪意のあるコードを挿入する攻撃手法です。テンプレートエンジンは、Webページの動的生成に使われるため、SSTIを利用されると、サーバー側でコードが実行され、システム情報の取得や任意コードの実行が可能になり、深刻なセキュリティリスクが発生します。
SSTIは、ユーザー入力がテンプレートエンジンに渡され、適切なサニタイズが行われていない場合に発生する可能性があり、Flask、Django、Ruby on Rails、Thymeleafなど、さまざまなテンプレートエンジンが対象になります。特に、クラウド環境やマイクロサービス構成のWebアプリケーションでは、この脆弱性が悪用されやすいため、注意が必要です。
SSTIの仕組み
SSTIは、テンプレートエンジンが外部から渡された入力値を処理する際に、その入力値にテンプレートエンジンのコードが含まれている場合に発生します。テンプレートエンジンは、ユーザー入力を含むデータをパースし、Webページを生成するため、このコードがサーバー上で実行されてしまいます。攻撃者はこれを悪用して、任意のコードを挿入し、サーバーで実行させることができます。
SSTIの攻撃例
たとえば、以下のような構文でテンプレートが構成されている場合を考えます:
from flask import Flask, render_template_string, request
app = Flask(__name__)
@app.route('/greet')
def greet():
name = request.args.get('name')
template = "Hello, {{ name }}!"
return render_template_string(template, name=name)
ここで、name
パラメータに悪意のあるコードを含めると、例えば次のように動作します:
http://example.com/greet?name={{7*7}}
このリクエストにより、テンプレートエンジンが{{7*7}}
を処理し、結果として49がページ上に表示されます。さらに、この手法を発展させることで、PythonやRubyなどのコマンドが実行され、機密情報へのアクセスやシステム改ざんが可能になります。
SSTIの影響とリスク
SSTIの影響は、テンプレートエンジンによって異なりますが、一般的には以下のようなリスクを伴います:
- 任意コードの実行
サーバーサイドでコードが実行されるため、攻撃者はシステムのファイルにアクセスしたり、外部サーバーとの通信を試みたりできます。結果として、システムの制御が奪われるリスクが高まります。 - 機密情報の漏洩
サーバーに保存されたファイルや環境変数などにアクセスされ、データベースの認証情報やシークレットキーなどが盗まれる可能性があります。 - 横展開(Lateral Movement)
SSTIによりサーバーへのフルアクセスが得られた場合、ネットワーク内の他のシステムにアクセスし、攻撃が拡散するリスクがあります。 - サービス停止(DoS)
無限ループや過剰なリソース消費を引き起こすコードを挿入されることで、サーバーが過負荷に陥り、サービスが停止するリスクがあります。
SSTIが発生しやすいテンプレートエンジン
SSTIは、以下のようなテンプレートエンジンで発生することがあります:
- Jinja2(Python)
Flaskなどで使用されるPythonのテンプレートエンジンで、{{ }}
の構文を使って式の評価が行われます。 - Freemarker(Java)
{{ }}
や${}
の構文を使い、動的なコンテンツの生成が可能で、特にサーバーサイドインジェクションに狙われやすいです。 - Thymeleaf(Java)
Springフレームワークで使用されるテンプレートエンジンで、式の評価や動的生成が可能なため、不正なコードが渡されるとリスクがあります。 - Ruby on RailsのERB
Rubyコードを埋め込んで評価できるテンプレートエンジンで、外部入力が直接評価されるとインジェクションが発生します。
SSTIの対策
- ユーザー入力のサニタイズ
テンプレートエンジンに渡す前に、ユーザー入力をサニタイズし、特殊文字やコードが含まれていないことを確認します。 - テンプレートエンジンの安全な利用
テンプレートエンジンの設定を強化し、式の評価機能を必要以上に使用しないようにします。特にJinja2などでは、autoescape
オプションを有効にすることが推奨されます。 - 入力のホワイトリスト管理
テンプレートに渡すデータは、事前に許可された値のみが含まれるようにホワイトリストを使用します。これにより、予期しない入力がテンプレートエンジンに渡されることを防ぎます。 - 静的テンプレートの使用
動的テンプレートよりも、可能であれば静的テンプレートを使用し、ユーザー入力を直接テンプレートエンジンで処理しないようにします。 - セキュリティテストとコードレビュー
SSTIの脆弱性が存在する可能性のあるコードには、定期的にセキュリティテストを実施し、脆弱性の発見に努めます。また、コードレビューを通じて、外部入力がテンプレートに渡される箇所を確認します。
SSTIの検出方法
- 静的解析ツールの利用
セキュリティスキャンツールや静的解析ツールを使い、SSTIのリスクがある箇所を検出します。これにより、特定のテンプレートエンジンの不適切な利用がないか確認できます。 - ペネトレーションテスト
SSTIの脆弱性を持つ可能性のあるエンドポイントに対して、テンプレートエンジンの構文を用いたテストを実施し、実際にサーバーサイドでコードが評価されるかを確認します。 - ログと監視
予期しないテンプレート評価や不審なエラーメッセージが発生していないか、ログを監視し、異常を検出します。
まとめ
SSTI(Server-Side Template Injection)は、テンプレートエンジンの脆弱性を悪用し、サーバー側で任意コードを実行する攻撃手法です。特にユーザー入力がテンプレートに直接渡される場合、システムの機密情報の漏洩や任意コードの実行、DoS攻撃などのリスクが高まります。適切なサニタイズ、ホワイトリストの使用、テンプレートエンジン設定の強化により、SSTIのリスクを軽減することが重要です。