コンテンツにスキップ

Template Injection

テンプレートインジェクション

説明

テンプレートインジェクションは、攻撃者がテンプレートでレンダリングされたテキストに悪意のあるコードをインジェクションし、サーバーで実行できるようにする脆弱性です。これにより、データの盗難、権限の昇格、リモートコード実行など、さまざまな攻撃が発生する可能性があります。テンプレートインジェクション攻撃は、検出が困難であり、攻撃者に危険な機能を提供する可能性があるため、特に危険です。

ここでは、ユーザー入力(userName)からの直接の連結を使用してテンプレート文字列を作成し、ユーザーがテンプレートの構造を制御できるようにしているため、コードに脆弱性があります。ユーザーがMustacheテンプレートタグを含む文字列を提供した場合、テンプレートインジェクションにつながる可能性があります。

import 'dart:io';
import 'package:mustache_template/mustache_template.dart';

Future main() async {
  var server = await HttpServer.bind(
    InternetAddress.loopbackIPv4,
    8080,
  );
  print('Listening on localhost:${server.port}');

  await for (HttpRequest request in server) {
    final userName = request.uri.queryParameters['name'] ?? 'guest';
    // Vulnerable to template injection due to template string concatenation
    final template = 'Hello, ${userName}';
    final output = Template(template, lenient: true, htmlEscapeValues: false)
        .renderString({});
    request.response
      ..write(output)
      ..close();
  }
}
import com.github.mustachejava.DefaultMustacheFactory
import com.github.mustachejava.Mustache
import io.ktor.application.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.http.Parameters

fun main() {
    embeddedServer(Netty, port = 8080) {
        routing {
            get("/") {
                val parameters: Parameters = call.request.queryParameters
                val userName = parameters["name"] ?: "guest"

                // Vulnerable to template injection due to template string concatenation
                val mf = DefaultMustacheFactory()
                val mustache: Mustache = mf.compile("template", "Hello, $userName")

                val writer = StringWriter()
                mustache.execute(writer, emptyMap<String, Any>())
                writer.flush()

                call.respondText(writer.toString())
            }
        }
    }.start(wait = true)
}

推奨事項

この脆弱性を軽減するには、サーバー側のテンプレートエンジンに渡される前に、すべてのユーザー入力が適切にサニタイズおよび検証されていることを確認することが重要です。

テンプレートエンジンには通常、テキストに安全に埋め込まれるコンテキストを受け取るrenderメソッドがあります。

import 'dart:io';
import 'package:mustache_template/mustache_template.dart';

Future main() async {
  var server = await HttpServer.bind(
    InternetAddress.loopbackIPv4,
    8080,
  );
  print('Listening on localhost:${server.port}');

  await for (HttpRequest request in server) {
    final userName = request.uri.queryParameters['name'] ?? 'guest';
    // Vulnerable to template injection due to template string concatenation
    final template = 'Hello, {{ username }}';
    final output = Template(template, lenient: true, htmlEscapeValues: false)
        .renderString({'username': username});
    request.response
      ..write(output)
      ..close();
  }
}
import com.github.mustachejava.DefaultMustacheFactory
import com.github.mustachejava.Mustache
import io.ktor.application.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.http.Parameters
import java.io.StringWriter

fun main() {
    embeddedServer(Netty, port = 8080) {
        routing {
            get("/") {
                val parameters: Parameters = call.request.queryParameters
                val userName = parameters["name"] ?: "guest"

                // Use a predefined template and pass untrusted data as values
                val mf = DefaultMustacheFactory()
                val mustache: Mustache = mf.compile("template", "Hello, {{name}}")

                val writer = StringWriter()
                mustache.execute(writer, mapOf("name" to userName))
                writer.flush()

                call.respondText(writer.toString())
            }
        }
    }.start(wait = true)
}

リンク

標準

  • OWASP_MASVS_L1:
    • MSTG_PLATFORM_2
  • OWASP_MASVS_L2:
    • MSTG_PLATFORM_2
  • PCI_STANDARDS:
    • REQ_2_2
    • REQ_6_2
    • REQ_6_3
    • REQ_11_3
  • OWASP_MASVS_v2_1:
    • MASVS_CODE_4
  • 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