Substitusi Template di Sisi Host
Sisipkan nilai hasil render server (misalnya placeholder bergaya template Go `{{ .Field }}`) ke dalam JavaScript hasil obfuskasi VM tanpa merusak alur obfuskasi.
Masalahnya
Backend Anda (Go, Rails, Django, PHP, …) menyajikan berkas JavaScript yang isinya sebagian harus dirender
per permintaan: endpoint API, daftar feature flag, blob state awal, ID build, atau nonce. Anda mengobfuskasi
JS tersebut dengan vmObfuscation: true, tetapi Anda juga memerlukan template engine untuk mengganti placeholder di
keluaran hasil obfuskasi setelah obfuskasi selesai. reservedNames dan reservedStrings menjaga placeholder tetap terlihat
di keluaran sehingga dapat diganti. Tanpa keduanya, placeholder string terserap ke dalam bytecode VM dan placeholder pengenal
dituliskan di beberapa tempat yang telah ditulis ulang, sehingga template engine tidak menemukan apa pun untuk diganti atau
malah merusak keluaran.
Pertimbangkan memuat nilai sebagai data
Jika memungkinkan, hindari mengedit keluaran terlindungi sama sekali: muat konfigurasi runtime sebagai data sebelum
bundel terlindungi berjalan. Simpan di skrip terpisah atau ambil dari endpoint yang terautentikasi. Cara ini menjaga
keluaran terlindungi tetap utuh, sehingga vmSelfDefending dapat tetap aktif. Data yang dikirim ke peramban bagaimanapun
tetap terlihat oleh peramban tersebut.
Gunakan pola di bawah ini ketika nilai-nilai tersebut memang harus disubstitusikan ke dalam berkas hasil obfuskasi.
Catatan tentang contoh Go: contoh-contoh tersebut melakukan penggantian string biasa (strings.ReplaceAll / strings.NewReplacer) pada
keluaran hasil obfuskasi dan menangani escaping-nya sendiri, seperti yang ditunjukkan pada setiap pola. Contoh tersebut tidak dijalankan melalui paket
html/template Go - paket itu akan menerapkan escaping JavaScript kontekstualnya sendiri di atasnya, sehingga payload mengalami escaping dua kali. Jika Anda
memang merender melalui html/template, hilangkan escaping manual dan biarkan engine melakukan escaping sekali saja.
Opsi mana yang harus dipilih?
| Nilai server berupa… | Gunakan |
|---|---|
| Nilai JS mentah (array, objek, angka, boolean - nilai JSON apa pun) | Pola 1 - reservedNames + placeholder pengenal |
| String (kasus umum - JSON hasil render, ID build, nonce) | Pola 2 - reservedStrings + placeholder template literal |
| String, ketika kode harus tetap ES5 atau API di sekitarnya membutuhkan literal string bertanda kutip | Pola 3 - reservedStrings + placeholder string bertanda kutip |
Substitusi setelah obfuskasi tidak kompatibel dengan vmSelfDefending: true. Lihat
Catatan kompatibilitas di akhir resep ini.
Pola 1 - reservedNames dengan placeholder pengenal
Paling cocok untuk: menyisipkan ekspresi JS mentah (array, objek, angka, …) tanpa perlu memikirkan escaping tanda kutip.
Pilih pengenal khas yang tidak akan pernah bertabrakan dengan kode sungguhan, rujuk secara langsung, dan cantumkan regex
yang cocok dengannya di reservedNames. Di bawah obfuskasi VM, pengenal tersebut dialirkan melalui array reserved-expressions
dan muncul apa adanya di keluaran, misalnya:
Ganti pengenal dengan ekspresi lengkap hasil serialisasi JSON. Jangan menempelkan nilai di dalam tanda kutip atau backtick:
pengenal tersebut tidak berada di dalam literal string, sehingga nilai yang disisipkan diurai oleh engine JS sebagai
ekspresi biasa. Gunakan serializer tepercaya, lakukan escaping pada < ketika skrip disematkan dalam HTML, dan uji nilai yang berisi
tanda kutip, backslash, baris baru, backtick, dan ${...}.
Pola 2 - reservedStrings dengan placeholder template literal
Paling cocok untuk: template engine bergaya Go / Jinja yang mewajibkan delimiter seperti {{ .Field }}, yang kebetulan
merupakan teks JS yang valid bila dibungkus backtick.
Placeholder berada di dalam template literal dengan satu quasi dan tanpa interpolasi. Di bawah obfuskasi VM, ini dialirkan melalui array reserved-expressions, sehingga bentuk backtick mentahnya tetap terjaga di keluaran.
Sumber
Opsi obfuscator
UI
Untuk mencadangkan placeholder {{.Config.FeatureFlags}} dari sumber di atas, tambahkan regex ini ke field Reserved Strings
dengan backslash tunggal. UI menyimpan nilai apa adanya, jadi tidak seperti di kode JS, backslash tidak
digandakan:

API
Setelah obfuskasi
Placeholder dipertahankan byte demi byte, termasuk backtick yang mengapitnya.
Substitusi di sisi host
Ganti {{.Config.FeatureFlags}} dengan string JSON yang sudah diberi escaping untuk template literal. Backtick tidak memerlukan escaping
" di dalamnya, tetapi backslash, backtick, atau ${ di dalam payload tetap akan mengubah atau mengakhiri literal, jadi lakukan escaping
pada ketiganya:
Saat runtime: JSON.parse(`{"newCheckout":true,"darkMode":false}`) - berfungsi.
Mengapa template literal lebih disukai daripada tanda kutip tunggal/ganda untuk nilai string? Backtick tidak memerlukan escaping "
di dalam payload JSON. Ini penting karena sebagian besar nilai hasil render server adalah JSON, dan JSON penuh dengan tanda
kutip ganda. Dengan placeholder bertanda kutip ganda, Anda harus melakukan escaping pada setiap " di dalamnya (lihat Pola 3); dengan backtick,
payload hanya perlu escaping pada backslash, backtick, dan ${ yang jarang muncul.
Pola 3 - reservedStrings dengan placeholder string bertanda kutip
Paling cocok untuk: kode sumber yang harus tetap ES5 (tanpa template literal), atau kasus ketika API di sekitarnya mengharapkan literal string biasa.
Placeholder berupa literal string bertanda kutip tunggal atau ganda. Di bawah obfuskasi VM, ini dialirkan melalui
array reserved-strings, yang dikeluarkan sebagai array JS hasil serialisasi JSON.stringify - selalu bertanda kutip ganda,
apa pun gaya tanda kutip pada masukan.
Sumber
Opsi obfuscator
UI
Untuk mencadangkan placeholder {{.Page.Tags}} dari sumber di atas, tambahkan regex ini ke field Reserved Strings
dengan backslash tunggal. UI menyimpan nilai apa adanya, jadi tidak seperti di kode JS, backslash tidak digandakan:

API
Setelah obfuskasi
Substitusi di sisi host
Karena placeholder berada di dalam string JS bertanda kutip ganda, payload JSON yang disisipkan harus diberi escaping pada backslash dan
karakter " di dalamnya:
Keluaran yang dihasilkan:
Saat runtime: JSON.parse("[\"news\",\"tech\",\"release\"]") → ["news","tech","release"].
Jika Anda lupa melakukan escaping, peramban akan melihat tanda kutip yang tidak seimbang dan melempar SyntaxError. Pola 2
menghindari tanda kutip ganda sepenuhnya dengan menggunakan backtick.
Beberapa placeholder dalam satu program
Ketiga pola dapat dipadukan. Satu regex reservedStrings dengan alternasi dapat mencocokkan setiap bentuk placeholder yang
dikeluarkan template engine Anda - di sini, gaya {{ .Field }} maupun %{ .Field }:
Anda dapat mencampur placeholder pengenal (untuk nilai JS mentah) dan placeholder string (untuk JSON hasil render) dalam sumber yang sama; pilih per placeholder berdasarkan apa yang benar-benar akan disisipkan oleh server.
Catatan kompatibilitas
vmSelfDefending merusak substitusi setelah obfuskasi
VM Self Defending mendeteksi setiap perubahan pada keluaran hasil obfuskasi setelah build, termasuk substitusi template yang sah, dan kode terlindungi kemudian menolak berjalan.
Jika Anda mengandalkan substitusi template di sisi host, setel vmSelfDefending: false. Biarkan selfDefending juga nonaktif:
opsi ini tidak berpengaruh di bawah obfuskasi VM, dan tanpa VM opsi ini juga melarang perubahan apa pun pada keluaran.
Tips placeholder
- Jangan memakai ulang placeholder untuk pengenal dan string sekaligus. Nama tercadang seperti
__TOKEN__dan string tercadang yang cocok dengan__TOKEN__menggambarkan dua jalur kode yang berbeda (array reserved-expressions vs. array reserved-strings). Gunakan bentuk teks yang berbeda untuk masing-masing, misalnya konvensiUPPER_SNAKEuntuk placeholder pengenal dan bentuk yang dibungkus delimiter ({{ ... }},%{...},<<<...>>>) untuk placeholder string. Dengan begitu, bug pada satu regex tidak dapat diam-diam mencocokkan yang lain. - Regex
reservedStringsdijalankan terhadap nilai string mentah. Regex dicocokkan dengan nilai runtime string, bukan teks sumbernya.\{\{[^}]+\}\}mencocokkan string yang mengandung{{.something}}(atau bentuk{{...}}lainnya). Jika placeholder Anda mungkin dibungkus konten tambahan ("prefix-{{.Field}}-suffix"), regex tetap cocok tetapi seluruh string dipertahankan, jadi rencanakan substitusi Anda dengan memperhitungkannya. - Berfungsi dengan template engine apa pun. Meskipun contohnya menggunakan sintaks Go, tidak ada bagian integrasi javascript-obfuscator yang khusus untuk Go. Apa pun yang dapat melakukan penggantian tingkat string pada keluaran obfuscator akan berfungsi: Rails ERB, Django, short tag PHP, sed dalam pipeline CI, dan sebagainya. Pilih delimiter yang secara alami dikeluarkan oleh engine Anda dan tidak bertabrakan dengan sintaks JS sungguhan.
