Dokümantasyon
/
Tarifler
/

Sunucu Tarafında Şablon Değişimi

Sunucu Tarafında Şablon Değişimi

Pro
v6.10.0+

Sunucuda oluşturulan değerleri (örn. Go şablon tarzı `{{ .Field }}` yer tutucuları) obfuscation hattını bozmadan VM ile obfuscate edilmiş JavaScript koduna enjekte edin.

Sorun

Arka ucunuz (Go, Rails, Django, PHP, …), içeriğinin istek başına kısmen oluşturulması gereken bir JavaScript dosyası sunar: bir API uç noktası, özellik bayraklarının listesi, bir başlangıç durumu verisi, bir derleme kimliği, bir nonce. JS kodunu vmObfuscation: true ile obfuscate edersiniz, ancak şablon motorunun obfuscation tamamlandıktan sonra obfuscate edilmiş çıktıdaki yer tutucuları değiştirmesine de ihtiyacınız vardır. reservedNames ve reservedStrings, bir yer tutucunun değiştirilebilmesi için çıktıda görünür kalmasını sağlar. Bunlar olmadan bir string yer tutucusu VM bayt koduna dahil edilir, bir tanımlayıcı yer tutucusu ise yeniden yazılmış birkaç yerde üretilir; bu yüzden şablon motoru ya değiştirecek hiçbir şey bulamaz ya da çıktıyı bozar.

Bunun yerine değerleri veri olarak yüklemeyi düşünün

Mümkünse korunan çıktıyı hiç düzenlemeyin: çalışma zamanı yapılandırmasını korunan paket çalışmadan önce veri olarak yükleyin. Onu ayrı bir betikte tutun veya kimliği doğrulanmış bir uç noktadan alın. Bu, korunan çıktıyı olduğu gibi bırakır; böylece vmSelfDefending etkin kalabilir. Bir tarayıcıya iletilen veri her iki durumda da o tarayıcı tarafından görülebilir.

JavaScript

Değerlerin gerçekten obfuscate edilmiş dosyanın içine yerleştirilmesi gerektiğinde aşağıdaki kalıpları kullanın.

Go örnekleri hakkında bir not: bu örnekler obfuscate edilmiş çıktı üzerinde düz bir string değiştirme (strings.ReplaceAll / strings.NewReplacer) yapar ve kaçış işlemini, her kalıpta gösterildiği gibi, kendileri halleder. Go'nun html/template paketinden geçirilmezler - bu paket kendi bağlama duyarlı JavaScript kaçışını üstüne ekleyerek yükü iki kez kaçışlardı. html/template üzerinden işliyorsanız elle yapılan kaçışı kaldırın ve motorun bir kez kaçışlamasına izin verin.

Hangi seçeneği seçmeliyim?

Sunucu değeri…Kullanın
Ham bir JS değeri (dizi, nesne, sayı, boolean - herhangi bir JSON değeri)Kalıp 1 - reservedNames + tanımlayıcı yer tutucusu
Bir string (yaygın durum - işlenmiş JSON, bir derleme kimliği, bir nonce)Kalıp 2 - reservedStrings + şablon değişmezi yer tutucusu
Bir string; kodun ES5 kalması gerekiyor veya çevreleyen API tırnaklı bir string değişmezi istiyorKalıp 3 - reservedStrings + tırnaklı string yer tutucusu

Obfuscation sonrası değiştirme vmSelfDefending: true ile uyumsuzdur. Bu tarifin sonundaki Uyumluluk notları bölümüne bakın.

Kalıp 1 - tanımlayıcı yer tutucusuyla reservedNames

En uygun kullanım: tırnak kaçışı endişesi olmadan ham JS ifadelerini (diziler, nesneler, sayılar, …) enjekte etmek.

Gerçek kodla asla çakışmayacak ayırt edici bir tanımlayıcı seçin, ona doğrudan başvurun ve onunla eşleşen bir düzenli ifadeyi reservedNames içinde listeleyin. VM obfuscation altında tanımlayıcı, ayrılmış ifadeler dizisi üzerinden yönlendirilir ve çıktıda olduğu gibi görünür, örneğin:

JavaScript

Tanımlayıcıyı eksiksiz, JSON olarak serileştirilmiş bir ifadeyle değiştirin. Değeri tırnak veya ters tırnak içine yapıştırmayın: tanımlayıcı bir string değişmezinin içinde değildir; bu nedenle enjekte edilen değer JS motoru tarafından sıradan bir ifade olarak ayrıştırılır. Güvenilir bir serileştirici kullanın, betik HTML'e gömülüyse < karakterini kaçışlayın ve tırnak işaretleri, ters eğik çizgiler, satır sonları, ters tırnaklar ve ${...} içeren değerleri test edin.

JavaScript

Kalıp 2 - şablon değişmezi yer tutucusuyla reservedStrings

En uygun kullanım: ters tırnaklarla sarıldığında geçerli JS metni olan {{ .Field }} gibi sınırlayıcılar gerektiren Go / Jinja tarzı şablon motorları.

Yer tutucu, tek parçalı, enterpolasyon içermeyen bir şablon değişmezinin içinde yer alır. VM obfuscation altında bu, ayrılmış ifadeler dizisi üzerinden yönlendirilir ve çıktıda ham ters tırnaklı biçim korunur.

Kaynak

JavaScript

Obfuscator seçenekleri

Arayüz

Yukarıdaki kaynaktaki {{.Config.FeatureFlags}} yer tutucusunu ayırmak için bu düzenli ifadeyi Reserved Strings alanına tek ters eğik çizgilerle ekleyin. Arayüz değeri olduğu gibi saklar; bu nedenle JS kodundakinin aksine ters eğik çizgiler iki katına çıkarılmaz:

Metin

Obfuscator arayüzündeki Reserved Strings alanı, düzenli ifade tek ters eğik çizgilerle girilmiş halde

API

JavaScript

Obfuscation sonrasında

JavaScript

Yer tutucu, çevreleyen ters tırnaklar dahil bayt bayt korunur.

Sunucu tarafında değiştirme

{{.Config.FeatureFlags}} yer tutucusunu, şablon değişmezi için kaçışlanmış bir JSON string'iyle değiştirin. Ters tırnaklar içteki " karakterlerinin kaçışlanmasını gerektirmez, ancak veri içindeki bir ters eğik çizgi, bir ters tırnak veya ${ yine de değişmezi değiştirir ya da sonlandırır; bu nedenle bu üçünü kaçışlayın:

Kod

Çalışma zamanında: JSON.parse(`{"newCheckout":true,"darkMode":false}`) - çalışır.

String değerleri için neden tek/çift tırnak yerine şablon değişmezleri tercih edilmeli? Ters tırnaklar, JSON verisinin içindeki " karakterlerinin kaçışlanmasını gerektirmez. Bu önemlidir, çünkü sunucuda oluşturulan değerlerin çoğu JSON'dur ve JSON çift tırnaklarla doludur. Çift tırnaklı bir yer tutucuyla içteki her " karakterini kaçışlamanız gerekir (bkz. Kalıp 3); ters tırnaklarla ise verinin yalnızca nadir görülen ters eğik çizgilerini, ters tırnaklarını ve ${ dizilerini kaçışlamanız gerekir.

Kalıp 3 - tırnaklı string yer tutucusuyla reservedStrings

En uygun kullanım: ES5'te kalması gereken (şablon değişmezi kullanılamayan) kaynak kod veya çevreleyen API'nin normal bir string değişmezi beklediği durumlar.

Yer tutucu, tek veya çift tırnaklı bir string değişmezidir. VM obfuscation altında ayrılmış string'ler dizisi üzerinden yönlendirilir; bu dizi JSON.stringify ile serileştirilmiş bir JS dizisi olarak üretilir ve girdideki tırnak stilinden bağımsız olarak her zaman çift tırnaklıdır.

Kaynak

JavaScript

Obfuscator seçenekleri

Arayüz

Yukarıdaki kaynaktaki {{.Page.Tags}} yer tutucusunu ayırmak için bu düzenli ifadeyi Reserved Strings alanına tek ters eğik çizgilerle ekleyin. Arayüz değeri olduğu gibi saklar; bu nedenle JS kodundakinin aksine ters eğik çizgiler iki katına çıkarılmaz:

Metin

Obfuscator arayüzündeki Reserved Strings alanı, düzenli ifade tek ters eğik çizgilerle girilmiş halde

API

JavaScript

Obfuscation sonrasında

JavaScript

Sunucu tarafında değiştirme

Yer tutucu çift tırnaklı bir JS string'inin içinde bulunduğundan, enjekte edilen JSON verisinin ters eğik çizgileri ve içteki " karakterleri kaçışlanmalıdır:

Kod

Ortaya çıkan çıktı:

JavaScript

Çalışma zamanında: JSON.parse("[\"news\",\"tech\",\"release\"]") → ["news","tech","release"].

Kaçışlamayı unutursanız tarayıcı dengesiz tırnaklar görür ve bir SyntaxError fırlatır. Kalıp 2, ters tırnaklar kullanarak çift tırnak sorununu tamamen ortadan kaldırır.

Tek bir programda birden fazla yer tutucu

Üç kalıp birlikte kullanılabilir. Alternasyon içeren tek bir reservedStrings düzenli ifadesi, şablon motorunuzun ürettiği her yer tutucu biçimiyle eşleşebilir - burada hem {{ .Field }} hem de %{ .Field } stilleriyle:

JavaScript

Aynı kaynakta tanımlayıcı yer tutucularını (ham JS değerleri için) ve string yer tutucularını (oluşturulan JSON için) karıştırabilirsiniz; her yer tutucu için sunucunun gerçekte ne enjekte edeceğine göre seçim yapın.

Uyumluluk notları

vmSelfDefending obfuscation sonrası değiştirmeyi bozar

VM Self Defending, obfuscate edilmiş çıktıda derlendikten sonra yapılan her değişikliği (meşru bir şablon değişimi dahil) algılar ve korunan kod bu durumda çalışmayı reddeder.

Sunucu tarafında şablon değişimine dayanıyorsanız vmSelfDefending: false ayarlayın. selfDefending seçeneğini de kapalı bırakın: VM obfuscation altında hiçbir etkisi yoktur, ancak VM olmadan o da çıktıda herhangi bir değişikliği yasaklar.

Yer tutucu ipuçları

  • Yer tutucuları tanımlayıcılar ve string'ler arasında yeniden kullanmayın. __TOKEN__ gibi ayrılmış bir ad ile __TOKEN__ ile eşleşen ayrılmış bir string, iki farklı kod yolunu tanımlar (ayrılmış ifadeler dizisi ve ayrılmış string'ler dizisi). Her biri için farklı metinsel biçimler kullanın; örneğin tanımlayıcı yer tutucuları için UPPER_SNAKE kuralını, string yer tutucuları için ise sınırlayıcılarla sarılmış bir biçimi ({{ ... }}, %{...}, <<<...>>>). Böylece bir düzenli ifadedeki hata sessizce diğeriyle eşleşemez.
  • reservedStrings düzenli ifadeleri ham string değerleri üzerinde çalışır. Düzenli ifade kaynak metinle değil, string'in çalışma zamanındaki değeriyle eşleştirilir. \{\{[^}]+\}\}, {{.something}} (veya başka herhangi bir {{...}} biçimini) içeren string'lerle eşleşir. Yer tutucunuz ek içerikle sarılmış olabilirse ("prefix-{{.Field}}-suffix"), düzenli ifade yine eşleşir ancak string'in tamamı korunur; değiştirme işleminizi buna göre planlayın.
  • Herhangi bir şablon motoruyla çalışır. Örnekler Go söz dizimini kullansa da javascript-obfuscator entegrasyonunda Go'ya özgü hiçbir şey yoktur. Obfuscator çıktısı üzerinde string düzeyinde değiştirme yapabilen her şey çalışır: Rails ERB, Django, PHP kısa etiketleri, bir CI hattındaki sed vb. Motorunuzun doğal olarak ürettiği ve gerçek JS söz dizimiyle çakışmayan sınırlayıcılar seçin.