Apa Itu Server-Side Template Injection (SSTI)? Panduan Lengkap Cara Kerja, Eksploitasi, dan Pencegahannya

Bayangkan sebuah aplikasi web yang terlihat aman dari luar. Form login, halaman profil, dan dashboard berfungsi normal. Namun di balik layar, ada celah kecil yang bisa dimanfaatkan penyerang untuk mengeksekusi kode berbahaya langsung di server. Celah itu bernama Server-Side Template Injection (SSTI), sebuah kerentanan yang sering luput dari perhatian developer namun bisa berakibat fatal.

Menurut OWASP Foundation, SSTI termasuk dalam kategori Injection yang konsisten menempati posisi kritis dalam OWASP Top 10. Riset dari PortSwigger Research (James Kettle, 2015) yang pertama kali mempopulerkan istilah ini menunjukkan bahwa SSTI bisa ditemukan di berbagai template engine populer seperti Jinja2, Twig, Freemarker, dan Velocity. Yang membuatnya berbahaya: SSTI bisa berujung pada Remote Code Execution (RCE) dan pengambilalihan server sepenuhnya.

Artikel ini akan membahas secara lengkap apa itu SSTI, bagaimana cara kerjanya, dampaknya terhadap keamanan aplikasi, serta langkah-langkah pencegahannya. Cocok untuk developer web, security engineer, dan siapa pun yang ingin memahami salah satu ancaman injeksi paling serius di aplikasi modern. Baca juga: Apa Itu Command Injection? Panduan Lengkap Cara Kerja, Eksploitasi, dan Pencegahan untuk memahami jenis serangan injeksi lain yang juga mengincar server.

Ilustrasi kode pemrograman di layar komputer yang menunjukkan template engine dengan indikator kerentanan injeksi

Apa Itu Server-Side Template Injection (SSTI)?

Server-Side Template Injection (SSTI) adalah kerentanan keamanan web di mana penyerang bisa menyisipkan kode berbahaya ke dalam template yang diproses di sisi server. Template engine digunakan oleh framework web modern untuk memisahkan logika bisnis dari tampilan. Ketika input pengguna dimasukkan langsung ke dalam template tanpa sanitasi yang tepat, penyerang bisa mengeksploitasi sintaks native template engine tersebut.

Untuk memahami konsep ini, bayangkan template engine sebagai “form surat” dengan kolom yang bisa diisi. Nama penerima diambil dari database dan dimasukkan ke template: Halo {{ nama }}, selamat datang!. Jika pengguna mengirimkan {{ 7*7 }} sebagai nama dan hasilnya muncul sebagai Halo 49, selamat datang!, maka aplikasi tersebut rentan terhadap SSTI. Template engine mengeksekusi ekspresi matematika yang seharusnya hanya string biasa.

Perbedaan utama SSTI dengan Cross-Site Scripting (XSS) adalah lokasi eksekusinya. XSS dieksekusi di browser korban (client-side), sedangkan SSTI diproses langsung di server. Inilah yang membuat SSTI jauh lebih berbahaya: penyerang bisa membaca file sistem, mengakses database, bahkan mengambil alih server sepenuhnya. Berdasarkan OWASP Web Security Testing Guide (WSTG v4.1), pengujian SSTI harus menjadi bagian dari setiap audit keamanan aplikasi web modern.

Bagaimana Cara Kerja Serangan SSTI?

Serangan SSTI terjadi melalui beberapa tahapan. Pertama, penyerang mengidentifikasi apakah aplikasi menggunakan template engine. Kedua, penyerang menentukan jenis template engine yang digunakan. Ketiga, penyerang mengeksploitasi sintaks spesifik engine tersebut untuk mencapai eskalasi dari sekadar ekspresi sederhana menjadi eksekusi kode penuh.

Fase 1: Deteksi Awal

Penyerang biasanya memulai dengan mengirimkan payload sederhana untuk menguji kerentanan. Contoh payload deteksi yang umum digunakan:

{{ 7*7 }} atau ${7*7} atau <%= 7*7 %>. Jika output menampilkan 49 (hasil perkalian), ini adalah konfirmasi kuat bahwa input pengguna diproses sebagai kode template, bukan string literal. Berdasarkan penelitian PortSwigger Research, payload seperti {{ 'test'.toUpperCase() }} di Node.js atau {{ config.items() }} di Flask/Jinja2 bisa mengungkapkan informasi internal aplikasi.

Fase 2: Identifikasi Template Engine

Setelah kerentanan terkonfirmasi, langkah selanjutnya adalah mengidentifikasi template engine yang digunakan. Setiap engine memiliki sintaks unik. Berikut perbandingan sintaks beberapa template engine populer:

  • Jinja2 (Python/Flask): {{ ... }} untuk ekspresi, {% ... %} untuk statement
  • Twig (PHP/Symfony): {{ ... }} untuk output, {% ... %} untuk logika
  • Freemarker (Java): ${...} atau #{...} untuk ekspresi
  • Velocity (Java): #set(...), $variable untuk variabel
  • Handlebars (Node.js): {{ ... }}, tanpa logika kompleks bawaan
  • ERB (Ruby): <%= ... %> untuk output

Penyerang bisa menggunakan diagram keputusan (decision tree) yang dikembangkan oleh PortSwigger Research untuk memetakan perilaku payload ke engine spesifik. Misalnya, payload {{ '7'|add:'7' }} yang menghasilkan “14” mengindikasikan Django, sementara {{7*7}} yang menghasilkan “49” lebih umum di Jinja2 atau Twig.

Fase 3: Eksploitasi Menuju RCE

Ini adalah fase paling berbahaya. Setelah template engine teridentifikasi, penyerang akan mencoba membaca file sensitif atau mengeksekusi perintah sistem. Di Jinja2 (Flask), payload berikut bisa membaca file /etc/passwd: {{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}. Payload ini memanfaatkan Method Resolution Order (MRO) Python untuk mengakses class file dan membaca konten file sistem.

Untuk mencapai RCE di Jinja2, penyerang bisa menggunakan payload yang lebih kompleks. Payload ini memanggil subprocess.Popen melalui chain __subclasses__().

Di Twig (PHP), payload seperti {{ _self.env.registerUndefinedFilterCallback('system') }}{{ _self.env.getFilter('id') }} bisa mengeksekusi perintah sistem. Sementara di Freemarker (Java), <#assign ex="freemarker.template.utility.Execute"?new()> ${ex("id")} menjalankan command shell.

Diagram alur serangan SSTI yang menunjukkan tiga tahap: deteksi, identifikasi template engine, dan eksploitasi RCE

Apa Dampak SSTI terhadap Keamanan Aplikasi?

Dampak SSTI sangat serius karena kerentanan ini beroperasi di sisi server. Berbeda dengan XSS yang terbatas pada sesi browser korban, SSTI memberikan penyerang akses ke lingkungan server secara langsung. Berikut adalah dampak-dampak utama yang bisa terjadi:

  1. Remote Code Execution (RCE): Penyerang bisa menjalankan perintah sistem apa pun. Ini adalah eskalasi maksimal dari SSTI yang memungkinkan pengambilalihan server sepenuhnya.
  2. Pembacaan File Sensitif: File konfigurasi, kredensial database, kunci enkripsi, dan kode sumber bisa dibaca oleh penyerang melalui payload template.
  3. Server-Side Request Forgery (SSRF): Template engine bisa dimanfaatkan untuk membuat request ke sistem internal yang tidak bisa diakses dari luar.
  4. Denial of Service (DoS): Payload template yang kompleks atau infinite loop bisa menghabiskan resource server dan membuat layanan tidak responsif.
  5. Data Exfiltration: Data sensitif dari database atau sistem file bisa dikirim ke server yang dikendalikan penyerang.

CISA (Cybersecurity and Infrastructure Security Agency) secara rutin memasukkan kerentanan SSTI ke dalam katalog Known Exploited Vulnerabilities (KEV). Salah satu contoh nyata adalah CVE-2025-25108 yang memengaruhi aplikasi FileZen, di mana SSTI memungkinkan penyerang jarak jauh mengeksekusi kode arbitrer tanpa autentikasi. Kasus ini menunjukkan bahwa SSTI bukan sekadar kerentanan teoretis, melainkan ancaman nyata yang dieksploitasi secara aktif.

Bagaimana Cara Mendeteksi SSTI di Aplikasi?

Mendeteksi SSTI membutuhkan pendekatan sistematis. Berbeda dengan SQL Injection yang memiliki tools otomatis seperti sqlmap, deteksi SSTI masih mengandalkan kombinasi testing manual dan tools khusus. Berikut langkah-langkah deteksi yang direkomendasikan:

1. Identifikasi Titik Injeksi Potensial

Titik injeksi SSTI bisa muncul di mana pun input pengguna dirender dalam template. Lokasi umum meliputi: parameter URL, form input, header HTTP (User-Agent, Referer), cookie, nama file yang diupload, dan pesan error kustom. Aplikasi yang menampilkan nama pengguna, hasil pencarian, atau halaman “404 kustom” sering menjadi target utama.

2. Uji dengan Polyglot Payload

Polyglot payload adalah string yang mengandung sintaks dari berbagai template engine sekaligus. Contoh polyglot: ${{<%[%' " }}%. Jika karakter tertentu memicu error atau perubahan output, ini mengindikasikan template engine yang digunakan. Metode ini sangat efisien untuk pengujian awal sebelum menentukan engine spesifik.

3. Gunakan Tools Otomatis

Beberapa tools keamanan yang bisa membantu deteksi SSTI:

  • Tplmap: Tools open-source khusus untuk eksploitasi SSTI. Mendukung berbagai template engine dan bisa otomatisasi dari deteksi hingga RCE.
  • Burp Suite: Ekstensi “SSTI Detector” atau “Backslash Powered Scanner” bisa mendeteksi pola SSTI secara otomatis.
  • Nuclei: Template-based scanner dengan template khusus untuk kerentanan SSTI di berbagai CMS dan framework.

Baca juga: TryHackMe Walkthrough: OWASP Top 10 – Pelajari 10 Kerentanan Web Paling Berbahaya untuk latihan praktis mendeteksi berbagai jenis injeksi termasuk SSTI di lingkungan lab yang aman.

Bagaimana Cara Mencegah SSTI di Aplikasi Web?

Pencegahan SSTI membutuhkan pendekatan berlapis yang melibatkan praktik coding aman, konfigurasi yang tepat, dan pengujian keamanan berkelanjutan. Berikut adalah langkah-langkah pencegahan yang direkomendasikan oleh OWASP dan PortSwigger:

1. Jangan Gabungkan Input Pengguna dengan Template

Ini adalah aturan paling fundamental. Input pengguna harus diteruskan ke template sebagai data (konteks variabel), bukan sebagai bagian dari template itu sendiri. Contoh implementasi yang benar di Jinja2:

# SALAH - input jadi bagian template
template = "Halo " + user_input
render(template)

# BENAR - input sebagai variabel
render("Halo {{ nama }}", nama=user_input)

Pendekatan kedua memastikan bahwa apa pun yang dikirim pengguna akan selalu diperlakukan sebagai string literal. Template engine tidak akan pernah mencoba mengeksekusi sintaks yang terkandung dalam nilai variabel.

2. Gunakan Sandbox Environment

Jika bisnis membutuhkan pengguna untuk mengedit template (misalnya fitur email kustom), gunakan sandbox template engine. Sandbox membatasi akses template ke fungsi berbahaya. Contoh: Jinja2 memiliki SandboxedEnvironment yang memblokir akses ke method seperti __class__, __mro__, dan __subclasses__. Namun perlu dicatat bahwa sandbox bukan solusi sempurna – PortSwigger Research telah mendemonstrasikan beberapa teknik bypass sandbox di berbagai engine.

3. Terapkan Logikanya di Controller, Bukan di Template

Template engine idealnya hanya untuk rendering tampilan. Semua logika bisnis, validasi, dan sanitasi harus dilakukan di layer controller sebelum data mencapai template. Pola arsitektur Model-View-Controller (MVC) yang ketat membantu memisahkan kekhawatiran ini dengan jelas.

4. Lakukan Security Testing Secara Rutin

Integrasikan pengujian SSTI ke dalam pipeline CI/CD. Gunakan Static Application Security Testing (SAST) untuk mendeteksi pola penggabungan string template, dan Dynamic Application Security Testing (DAST) untuk menguji endpoint dengan payload SSTI. Tools seperti Semgrep bisa dikonfigurasi dengan aturan kustom untuk mendeteksi pola-pola berbahaya di kode sumber.

5. Konfigurasi Web Application Firewall (WAF)

WAF modern bisa mendeteksi dan memblokir payload SSTI umum. Konfigurasikan aturan untuk memblokir request yang mengandung sintaks template engine seperti {{, {%, ${, dan pola akses class Python. Namun WAF bukan pengganti untuk kode yang aman – penyerang yang terampil bisa menemukan cara untuk bypass aturan WAF.

Ilustrasi web developer menulis kode aman dengan checklist keamanan SSTI di layar monitor

Pertanyaan yang Sering Diajukan (FAQ)

Apakah SSTI sama dengan XSS?

Tidak. XSS (Cross-Site Scripting) dieksekusi di browser korban dan menyerang pengguna lain. SSTI dieksekusi di server dan menyerang server itu sendiri. Dampak SSTI jauh lebih serius karena bisa mengakibatkan pengambilalihan server sepenuhnya (Remote Code Execution), sementara XSS umumnya terbatas pada session hijacking atau defacement.

Framework apa yang paling rentan terhadap SSTI?

Framework yang menggunakan template engine dengan fitur ekspresi kaya (feature-rich) lebih rentan. Flask (Jinja2), Django (Django Template), Symfony (Twig), Spring Boot (Thymeleaf/Freemarker), dan Express.js (Handlebars/EJS/Pug) adalah framework yang sering menjadi target. Namun kerentanannya bukan pada framework, melainkan pada cara developer mengimplementasikan rendering template.

Apakah WAF cukup untuk mencegah SSTI?

Tidak. WAF bisa membantu sebagai lapisan pertahanan tambahan, tetapi tidak bisa diandalkan sebagai satu-satunya perlindungan. Penyerang bisa menggunakan teknik encoding, polymorphic payload, atau memanfaatkan fitur template engine yang tidak dikenal WAF. Pertahanan utama harus ada di level kode aplikasi dengan menerapkan prinsip pemisahan data dari template.

Bagaimana cara belajar mendeteksi SSTI secara praktis?

Platform seperti PortSwigger Web Security Academy menyediakan lab gratis untuk berlatih mendeteksi dan mengeksploitasi SSTI. TryHackMe dan HackTheBox juga memiliki room/machine yang mencakup SSTI. Untuk pemula, mulailah dengan memahami dasar template engine yang digunakan framework pilihan Anda, lalu lanjutkan ke lab praktis.

Kesimpulan

Server-Side Template Injection (SSTI) adalah kerentanan serius yang sering terabaikan dalam pengembangan aplikasi web modern. Berbeda dengan serangan client-side, SSTI memberikan penyerang akses langsung ke server dan berpotensi mengakibatkan Remote Code Execution (RCE) – mimpi buruk setiap developer dan security engineer.

Kunci pencegahan SSTI ada pada satu prinsip sederhana: jangan pernah menggabungkan input pengguna dengan template. Selalu perlakukan input sebagai data yang diteruskan melalui variabel. Kombinasikan dengan sandbox environment, pengujian keamanan rutin, dan WAF sebagai lapisan tambahan. Seperti yang ditekankan oleh OWASP, “Injection is still king” – dan SSTI adalah salah satu varian injeksi yang patut mendapat perhatian serius dari setiap tim pengembangan.

Keamanan aplikasi adalah tanggung jawab bersama. Mulai dari developer yang menulis kode, tim QA yang menguji, hingga engineer yang mengelola infrastruktur. Memahami SSTI dan cara mencegahnya adalah langkah penting dalam membangun aplikasi web yang tangguh.