FlawOpen

flawopen.com/SSTI/FreeMarker dan Velocity

Apakah template FreeMarker dan Velocity aman terhadap input pengguna?

CWE-1336: Server-Side Template InjectionHalaman referensi
Jawaban singkat

Nilai dari pengguna tetap menjadi data saat dimasukkan ke template tepercaya. Sumber template yang dikendalikan pengguna berbeda: pengguna dapat menulis ekspresi dalam bahasa template. Jangkauan kemampuannya bergantung pada versi, wrapper atau introspector, objek model, dan izin aplikasi. Jangan menganggap setiap injeksi template menjalankan perintah sistem operasi; perlakukan sumber template tak tepercaya sebagai logika yang dapat dieksekusi dan render di luar proses aplikasi.

RENTAN
// Risiko: mengurai data permintaan sebagai sumber template
String src = "Hello " + userSuppliedName;
Template t = new Template("t", src, cfg);
t.process(model, writer);

// Risiko: mengevaluasi string VTL yang dikendalikan pengguna
Velocity.evaluate(context, writer,
                  "log", userTemplate);
DIPERBAIKI
// Template classpath tepercaya; model hanya berisi nilai skalar
Configuration cfg = new Configuration(
    Configuration.VERSION_2_3_34);
cfg.setTemplateLoader(new ClassTemplateLoader(
    App.class, "/templates"));
cfg.setNewBuiltinClassResolver(
    TemplateClassResolver.ALLOWS_NOTHING_RESOLVER);
cfg.setObjectWrapper(new SimpleObjectWrapper(
    Configuration.VERSION_2_3_34));
Template t = cfg.getTemplate("hello.ftl");
Map<String,Object> model = Map.of(
    "name", userSuppliedName);
t.process(model, writer);

// Velocity: template tepercaya dan introspeksi terbatas (pertahanan berlapis)
Properties p = new Properties();
p.setProperty("resource.loaders", "class");
p.setProperty("resource.loader.class.class",
    ClasspathResourceLoader.class.getName());
p.setProperty("runtime.introspector.uberspect",
    SecureUberspector.class.getName());
VelocityEngine engine = new VelocityEngine();
engine.init(p);
Template vt = engine.getTemplate("hello.vm", "UTF-8");
VelocityContext vc = new VelocityContext();
vc.put("name", userSuppliedName);
vt.merge(vc, writer);

Mengapa mesin Java dapat mengekspos kemampuan berbahaya

Template mengevaluasi ekspresi terhadap model data, tetapi permukaan Java yang tersedia bergantung pada konfigurasi. Wrapper default FreeMarker dapat mengekspos properti dan metode JavaBean dari POJO sembarang; anggota yang tersedia bergantung pada wrapper dan kebijakan akses. Uberspect default Velocity memetakan properti VTL ke metode Java publik. Ini tidak berarti semua model memberi reflection tanpa batas: risikonya meningkat jika model berisi objek layanan, class loader, objek permintaan, atau kemampuan kuat lainnya. Utamakan map string dan nilai sederhana; berikan hanya field yang diperlukan template tepercaya.

Built-in ?new FreeMarker dapat membuat instance class yang menerapkan TemplateModel. Apache menyarankan pembatasan resolusi class untuk template yang diunggah; SAFER_RESOLVER masih mengizinkan sejumlah class, sedangkan ALLOWS_NOTHING_RESOLVER menolak semua resolusi. Kontrol ini tidak menggantikan wrapper terbatas dan model data minimal.

Cara mengurangi risiko dan memahami batasnya

Anggap pembatasan mesin sebagai pertahanan berlapis, bukan isolasi proses. Gunakan versi yang didukung, tinjau konfigurasi terhadap panduan resmi terkini, dan jauhkan rahasia serta objek berhak istimewa dari renderer.

Pertanyaan umum

Apakah Thymeleaf juga terdampak?

Ini risiko terkait tetapi berbeda. Nama view yang dikendalikan pengguna tidak otomatis menjadi kelemahan injeksi ekspresi. Tinjau aliran data spesifik menuju evaluasi Thymeleaf atau Spring Expression Language dan jangan membuat fragmen ekspresi dari input tak tepercaya. Perbarui integrasi dan pilih view melalui logika aplikasi tepercaya.

Hanya administrator yang dapat mengedit template. Apakah itu dapat diterima?

Penulis template dapat menggunakan kemampuan yang diekspos mesin dan model data; ini tidak selalu berarti eksekusi perintah sistem operasi. Perlakukan izin mengedit template sebagai hak sensitif untuk menulis kode, batasi kepada pemelihara tepercaya, dan audit perubahannya.

Mesin apa yang paling aman untuk template dari pengguna?

Mesin tanpa logika seperti Mustache dapat mengurangi permukaan ekspresi dan pemanggilan metode, tetapi encoding output, kendali sumber template, dan kemampuan helper tetap penting. Pilih mesin yang sesuai model kepercayaan dan isolasi proses render; jangan mengandalkan mesin JVM umum sebagai sandbox.

Sumber resmi dan referensi

Lihat juga SSTI: Penyebab, Dampak, dan Perbaikan Template Injection Apakah render_template_string() Jinja2 aman? Apa itu server-side template injection?