Template Injection
Injection de template
Description
L'injection de template est une vulnérabilité qui permet à un attaquant d'injecter du code malveillant dans un texte rendu par un template, qui peut ensuite être exécuté par le serveur. Cela peut conduire à divers types d'attaques, notamment le vol de données, l'élévation des privilèges et l'exécution de code à distance. Les attaques par injection de template sont particulièrement dangereuses car elles peuvent être difficiles à détecter et offrent des capacités redoutables à un attaquant.
Ici, le code est vulnérable car nous créons la chaîne de template en utilisant la concaténation directe à partir de l'entrée de l'utilisateur (userName), lui permettant de contrôler la structure du template. Cela peut conduire à une injection de template si l'utilisateur fournit une chaîne contenant des balises de template 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)
}
Recommandation
Pour atténuer cette vulnérabilité, il est important de s'assurer que toutes les entrées des utilisateurs sont correctement assainies et validées avant d'être transmises au moteur de template côté serveur.
Les moteurs de templates ont généralement une méthode render qui prend un contexte qui sera intégré de manière sécurisée dans le texte.
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)
}
Liens
Normes
- 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