Substitusi Template di Sisi Host
Injeksikan nilai hasil render server (mis. ekspresi Go html/template `{{ .Field }}`) ke dalam JavaScript hasil obfuskasi VM tanpa merusak pipeline obfuskasi.
Masalahnya
Backend Anda (Go, Rails, Django, PHP, …) menyajikan sebuah berkas JavaScript yang isinya harus dirender sebagian
per-permintaan - sebuah endpoint API, daftar feature flag, blob state awal, sebuah build id, sebuah nonce. Anda mengobfuskasi
JS tersebut dengan vmObfuscation: true, tetapi Anda juga membutuhkan template engine untuk mengganti placeholder pada keluaran
hasil obfuskasi setelah obfuskasi selesai. Jika placeholder tersebut terserap ke dalam bytecode VM (bawaan untuk string dan
pengenal), template engine tidak punya apa pun untuk digantikan.
Opsi mana yang saya pilih?
| Nilai dari server berupa… | Gunakan |
|---|---|
| Sebuah ekspresi JS mentah (literal larik, objek, angka, boolean, pemanggilan fungsi) | reservedNames + placeholder pengenal |
| Sebuah string, dan Anda mengendalikan delimiter templating-nya | reservedStrings + placeholder literal template |
Sebuah string, dan template engine memaksa delimiter tertentu (mis. Go {{ .Field }}) | reservedStrings + placeholder string atau literal template |
Pola 1 - reservedNames dengan placeholder pengenal
Terbaik untuk: menginjeksikan ekspresi JS mentah (larik, objek, angka, …) tanpa kekhawatiran soal escaping tanda kutip.
Pilih sebuah pengenal khas yang tidak akan pernah bertabrakan dengan kode nyata, rujuk secara langsung, dan daftarkan sebuah regex yang mencocokkannya
di reservedNames. Di bawah obfuskasi VM, pengenal tersebut dirutekan melalui larik reserved-expressions dan
muncul apa adanya di keluaran.
Sumber
(function () {
var initialState = __INITIAL_STATE__;
bootstrap(initialState);
})();
Opsi obfuscator
JavaScriptObfuscator.obfuscate(source, {
vmObfuscation: true,
reservedNames: ['^__INITIAL_STATE__$']
});
Setelah obfuskasi
Di suatu tempat pada keluaran, Anda akan menemukan sebuah larik reserved-expressions yang mirip dengan:
let _r = [__INITIAL_STATE__, /* …other entries… */];
Token __INITIAL_STATE__ selamat dari penggantian nama pengenal dan tidak terserap ke dalam bytecode VM.
Substitusi sisi host (contoh Go)
tpl := template.Must(template.New("obf.js").Parse(obfuscated))
tpl.Execute(w, map[string]any{
"InitialState": map[string]any{"user": "alice", "theme": "dark"},
})
…di mana template Go Anda mengganti token tersebut dengan sebuah ekspresi JS mentah:
{{ `__INITIAL_STATE__` }} → {{ .InitialState | toJSON }}
Hasil:
let _r = [{"user":"alice","theme":"dark"}, /* … */];
Tanpa tanda kutip, tanpa escaping - nilai yang diinjeksikan diurai oleh mesin JS sebagai ekspresi biasa.
Pola 2 - reservedStrings dengan placeholder literal template
Terbaik untuk: template engine bergaya Go / Jinja yang memerlukan delimiter seperti {{ .Field }} yang kebetulan valid sebagai
teks JS ketika dibungkus dalam backtick.
Placeholder berada di dalam literal template yang berkuasi-tunggal, tanpa interpolasi. Di bawah obfuskasi VM, ini dirutekan melalui larik reserved-expressions, sehingga bentuk backtick mentahnya dipertahankan di keluaran.
Sumber
(function () {
var featureFlags = JSON.parse(`{{.Config.FeatureFlags}}`);
applyFlags(featureFlags);
})();
Opsi obfuscator
UI
Untuk mereservasi placeholder {{.Config.FeatureFlags}} dari sumber di atas, tambahkan regex ini ke field Reserved Strings
- dengan backslash tunggal. UI menyimpan nilainya apa adanya, sehingga tidak seperti pada kode JS, backslash-nya tidak digandakan:
\{\{[^}]+\}\}

API
JavaScriptObfuscator.obfuscate(source, {
vmObfuscation: true,
reservedStrings: ['\\{\\{[^}]+\\}\\}']
});
Setelah obfuskasi
let _r = [`{{.Config.FeatureFlags}}`, /* … */];
Placeholder tersebut dipertahankan bita demi bita, termasuk backtick di sekitarnya.
Substitusi sisi host
Ganti {{.Config.FeatureFlags}} dengan sebuah string JSON yang valid - string tersebut akan berada di dalam backtick saat runtime, yang tidak
memerlukan escaping tanda kutip di dalamnya:
flagsJSON, _ := json.Marshal(config.FeatureFlags) // e.g. {"newCheckout":true,"darkMode":false}
out := strings.ReplaceAll(obfuscated, "{{.Config.FeatureFlags}}", string(flagsJSON))
Saat runtime: JSON.parse(`{"newCheckout":true,"darkMode":false}`) - berfungsi.
Pola 3 - reservedStrings dengan placeholder string berkutip
Terbaik untuk: kode sumber yang harus tetap ES5 (tanpa literal template), atau kasus di mana API di sekitarnya mengharapkan sebuah literal string biasa.
Placeholder adalah literal string berkutip tunggal atau ganda. Di bawah obfuskasi VM, ini dirutekan melalui larik
reserved-strings, yang dikeluarkan sebagai larik JS yang diserialisasi dengan JSON.stringify - selalu berkutip ganda tanpa
memandang gaya kutip masukannya.
Sumber
(function () {
var tags = JSON.parse("{{.Page.Tags}}");
renderTags(tags);
})();
Opsi obfuscator
UI
Untuk mereservasi placeholder {{.Page.Tags}} dari sumber di atas, tambahkan regex ini ke field Reserved Strings -
dengan backslash tunggal. UI menyimpan nilainya apa adanya, sehingga tidak seperti pada kode JS, backslash-nya tidak digandakan:
\{\{[^}]+\}\}

API
JavaScriptObfuscator.obfuscate(source, {
vmObfuscation: true,
reservedStrings: ['\\{\\{[^}]+\\}\\}']
});
Setelah obfuskasi
var _rs = ["{{.Page.Tags}}", /* … */];
Substitusi sisi host
Karena placeholder berada di dalam string JS berkutip ganda, payload JSON yang diinjeksikan harus memiliki karakter "
di dalamnya yang di-escape dengan \":
raw, _ := json.Marshal(page.Tags) // e.g. ["news","tech","release"]
// Escape " for embedding inside a JS double-quoted string.
escaped := strings.ReplaceAll(string(raw), `"`, `\"`)
out := strings.ReplaceAll(obfuscated, "{{.Page.Tags}}", escaped)
Keluaran hasilnya:
var _rs = ["[\"news\",\"tech\",\"release\"]", /* … */];
Saat runtime: JSON.parse("[\"news\",\"tech\",\"release\"]") → ["news","tech","release"].
Jika Anda lupa escaping-nya, peramban akan melihat tanda kutip yang tidak seimbang dan melempar SyntaxError. Pola 2 menghindari hal ini
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:
JavaScriptObfuscator.obfuscate(source, {
vmObfuscation: true,
reservedNames: ['^__INITIAL_STATE__$'],
reservedStrings: ['\\{\\{[^}]+\\}\\}']
});
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 sebenarnya akan diinjeksikan server.
Catatan kompatibilitas
- Jangan menggunakan ulang placeholder di antara pengenal dan string. Sebuah reserved name seperti
__TOKEN__dan sebuah reserved string yang mencocokkan__TOKEN__menggambarkan dua jalur kode yang berbeda (larik reserved-expressions vs. larik reserved-strings). Gunakan bentuk tekstual 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 lainnya. - Regex
reservedStringsdijalankan terhadap nilai string mentah. Regex dicocokkan terhadap nilai runtime dari string tersebut, bukan teks sumbernya.\{\{[^}]+\}\}mencocokkan string yang mengandung{{.something}}(atau bentuk{{...}}lainnya). Jika placeholder Anda mungkin dibungkus konten tambahan ("prefix-{{.Field}}-suffix"), regex tersebut tetap cocok tetapi seluruh string dipertahankan - rencanakan substitusi Anda sesuai dengan itu. - Berfungsi dengan template engine apa pun. Meskipun contohnya menggunakan sintaks Go
text/template, tidak ada apa pun dalam integrasi javascript-obfuscator yang khusus Go. Apa pun yang dapat melakukan penggantian pada tingkat string terhadap keluaran obfuscator akan berfungsi: Rails ERB, Django, PHP short-tag, sed dalam pipeline CI, dan sebagainya. Pilih delimiter yang dikeluarkan engine Anda secara alami dan yang tidak bertabrakan dengan sintaks JS nyata.
