コンテンツにスキップ

Server-side template injection (SSTI)

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

説明

SSTI (サーバーサイドテンプレートインジェクション) は、攻撃者がテンプレートエンジンに悪意のあるコードをインジェクションできる場合に発生するセキュリティ脆弱性です。テンプレートエンジンはWebアプリケーションで動的コンテンツを生成するために一般的に使用されており、SSTIは、ユーザーの入力がテンプレートに含まれる前に適切に検証またはサニタイズされていない場合に発生します。

# user_inputにユーザー制御データが含まれていると仮定する
user_input = params[:input]

# ERBの安全でない使用
template = ERB.new("<%= #{user_input} %>")
result = template.result(binding)

# 結果を出力する
puts result
// Vulnerable PHP code using Twig
$name = $_GET['name'];
echo $twig->render('greet.twig', ['name' => $name]);
# Jinja2を使用する脆弱なPythonコード
from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/greet')
def greet():
    # テンプレートにユーザー入力を直接注入する
    username = request.args.get('username')
    return render_template('greet.html', username=username)

推奨事項

  • 可能な限り、ユーザー入力からテンプレートを作成することを避けてください。
  • Mustacheなどのシンプルなロジックレスのテンプレートエンジンの使用を検討してください。
  • リスクのあるモジュールや機能が無効化されているサンドボックス環境でテンプレートをレンダリングしてください。
  • テンプレートに渡す前にユーザー入力をサニタイズしてください。

# app.rb
require 'sinatra'
require 'mustache'

class ExampleTemplate < Mustache
  def initialize(name)
    @name = name
  end

  def greeting
    "Hello, #{@name}!"
  end
end

get '/greet/:name' do
  name = params['name']
  template = ExampleTemplate.new(name)
  erb template.render
end
<!-- index.php -->
<?php
require 'Mustache/Autoloader.php';
Mustache_Autoloader::register();

$template = new Mustache_Engine;

$name = $_GET['name'] ?? 'World';
$data = ['name' => $name];
echo $template->render('Hello, {{name}}!', $data);
?>
from flask import Flask, render_template
from flask import request
import pystache

app = Flask(__name__)

# シンプルなMustacheテンプレートを定義する
template = """
<html>
<head>
    <title>Greeting Page</title>
</head>
<body>
    <h1>Hello, {{name}}!</h1>
</body>
</html>
"""

# Mustacheレンダラーを作成する
mustache_renderer = pystache.Renderer()

@app.route('/')
def greet_user():
    # URLから'name'クエリパラメータを取得する
    user_name = request.args.get('name', 'Guest')

    # ユーザーの名前でテンプレートをレンダリングする
    rendered_template = mustache_renderer.render(template, {'name': user_name})

    # レンダリングされたHTMLを返す
    return rendered_template

if __name__ == '__main__':
    app.run(debug=True)

リンク

基準

  • CWE_TOP_25:
    • CWE_94
  • GDPR:
    • ART_5
    • ART_32
  • PCI_STANDARDS:
    • REQ_6_5
    • REQ_11_3
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_3_4
    • CC_4_1
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5
  • HIPAA_CONTROLS:
    • SECURITY212
    • SECURITY213
    • SECURITY255