- David Bushell'ın sitesinin bazı kullanıcılarda uzun süredir bozuk görünmesinin nedeni, Grammarly tarayıcı eklentisinin sayfaya gizlice enjekte ettiği CSS çıktı
- Firefox'ta Grammarly eklentisi, yerel eklenti varlıklarından bir stil sayfası ekliyor; bunu web sayfasının
StyleSheetList'iyle bulmak zor ve Content Security Policy'yi de atlatıyor
- Çakışma, Grammarly'nin
:root üzerinde küresel olarak tanımladığı --rem:16 ile sitenin akışkan tipografi hesaplaması için kullandığı --remin aynı adı taşımasından kaynaklandı
- Sitedeki
--rem, bir cascade layer içinde yer alıyordu ve layer dışındaki stillerin öncelikli olduğu CSS kuralı nedeniyle Grammarly'nin değeri hesabın üzerine yazabiliyordu
- Geçici olarak mutation observer ve
!important ile idare edildi, ancak nihai çözüm özellik adını --🤡 olarak değiştirmek oldu; bir eklenti küresel :root içine sıradan bir ad enjekte ettiğinde web sayfasıyla kolayca çakışabiliyor
Sayfanın içine giren Grammarly CSS'i
- Aylar boyunca site düzeninin kaydığı ve boyutların tuhaf göründüğüne dair aralıklı bildirimler geldi; ekran görüntüleri de paylaşıldı
- Teknik konulara hakim okurlar Grammarly browser extension'ı başlıca neden olarak işaret etti ve David Bushell bunu Firefox tabanlı Mullvad browser üzerinde doğrudan kurup doğruladı
- Eklenti kurulduğunda istenen izinler şunları içeriyor
- tüm web sitesi verilerine erişim
- bildirim gösterme
- tarayıcı sekmelerine erişim
- Grammarly, web sayfasına yerel eklenti varlıklarından yüklenen bir stil sayfası enjekte ediyor
- Bu stil sayfası web sayfasının StyleSheetList arayüzüyle bulunamıyor
- Content Security Policy'yi de atlatıyor
- Firefox'ta, sitenin kendisinin tespit etmesinin zor olduğu bir gizli stil sayfası gibi davranıyor
- Eklenti, kullanıcı etkileşime girmese bile tüm web sitelerinin
<html> belgesine <grammarly-desktop-integration> adlı özel öğeyi ekliyor
Tek bir --rem adının düzeni nasıl bozduğu
- Grammarly stil sayfasının sonunda şu CSS yer alıyor
:host,
:root {
--rem:16
}
- Aynı stil sayfasının başka bölümlerinde
--rem, yazı tipi boyutu ve satır yüksekliğini hesaplamak için kullanılıyor
.kE2Bj {
font-size:calc(0.86px*(var(--rem) - 2));
line-height:calc(1.2868px*(var(--rem) - 2));
}
- Site de kendi akışkan tipografi deneyi için
--rem adlı custom property'yi kullanıyordu
@layer base {
:root {
--rem: 0.0625rem;
--fluid: calc((100vi - (400 * var(--rem))) / (1920 - 400));
--font-size-h1: clamp(
calc(31 * var(--rem)),
calc((31 * var(--rem)) + (80 - 31) * var(--fluid)),
calc(80 * var(--rem))
);
}
}
- Sitenin
--rem değeri bir cascade layer içinde tanımlanmıştı ve layer dışındaki stiller, CSS specificity'den bağımsız olarak layer içindeki stillerden daha öncelikliydi
- Kaynak sırası da etkili olduğundan Grammarly'nin
--rem değeri baskın gelmiş olabilir
- Sonuç olarak sitenin hesaplamaları bozuldu ve düzen sorunları ortaya çıktı
- İlk aşamada, eklenen web component'i mutation observer ile tespit edip
!important stiller ekleyerek önlem alındı
- Kesin neden belirlendikten sonra sitenin custom property adı
--🤡 olarak değiştirildi
- Bu ad CSS'te geçerli bir custom property adıdır
--rem, Grammarly bunu küresel olarak kullandığı için çakışma riski taşıyan bir ad haline geldi
- Grammarly, rastgele sınıf adları üretmesine rağmen
--rem gibi genel bir custom property adını :root üzerinde küresel olarak uyguladı ve eklenti fiilen kullanılmasa bile tüm web sayfalarına kod enjekte etti
- Grammarly destek ekibiyle iletişime geçildi, ancak sorun henüz konuyu anlayan bir teknik sorumluya ulaşmış değil
1 yorum
Hacker News yorumları
Eklenti sorunu nedeniyle yaşadığım örnek biraz farklı. Coğrafi konum testleri için proxy sunucusu değiştirmeyi kolaylaştıran bir eklenti yayımlıyorum.
Birkaç ay önce berbat bir müşteri demosu yaptım; ürün sanki hiç çalışmıyormuş gibi görünüyordu. Uzun süre hata ayıkladıktan sonra, yakın zamanda yapılan bir 1Password eklentisi güncellemesinin bizim eklentiyi bozduğunu keşfettim. 1Password kimlik doğrulama olayına abone olmuştu ama geri dönmüyordu; bu yüzden zaman aşımına düşüyordu ve bizim abone çağrılmıyordu. Bizim eklenti tarayıcıya proxy sunucusunu değiştirmesini söyledikten sonra kimlik bilgilerini sağlamaya hazır bekliyordu, ama istek hiç gelmiyordu. 1Password destek ekibi Grammarly’den daha iyiydi, ancak destek ekibi üzerinden kim olduğu belirsiz bir PM’i öncelik konusunda ikna etmek zor
Daha sonra Rus hükümeti web siteleri için gereken bir eklentinin de aynı sorunu yaşadığını öğrendim
10 yıldan uzun süredir eklenti tarafında çalışan biri olarak, sonuçta sorumluluğun büyük kısmı Google’da. Reklam engelleyici değişikliğiyle ilgili politik mesele bir yana, Manifest v3 birçok açıdan beklenenden çok daha kötü.
Genel olarak Chromium kod tabanının kalitesi eskisine göre epey düşmüş gibi geliyor
Bilinmeyen sayfalara script veya stil enjekte ediyorsanız en azından değişken ad alanlarını ayırmanız gerekir
Ama mülakatı yapan kişi, bunları artık modern araçların zaten yaptığını ve herkesin yaptığını söyler gibi küçümseyerek geçiştirdi. Buna bir ölçüde katılmak zorunda kaldım, çünkü artık o işi yapmıyorum ve gerçekte bilmiyorum. Meğer herkes bunu yapmıyormuş
Bizim eklediklerimizle zaten var olanları net biçimde ayırt edebiliyor ve olası çakışmaları önleyebiliyorduk
Ekran paylaşımında veya kayıtta o yeşil davetsiz misafirin her web sitesinde varsayılan olarak yerleşik olduğunu görmek korkutucu. Bu yalnızca görsel olarak rahatsız edici olmakla kalmıyor; beraberinde gizlilik sorunları ve bariz bir saldırı vektörü de getiriyor.
Chrome’da eklentileri yalnızca gerektiğinde açmak mümkün; neden kimsenin bunu yapmadığını bilmiyorum. Bunun neden tüm tarayıcılarda varsayılan davranış olmadığını da merak ediyorum
Bazı çalışma arkadaşları bilginin üçüncü taraflara geçme ihtimalinden rahatsız olduğu için, eklentiler kapatılana kadar toplantıyı askıya alıyoruz
Grammarly Extension mühendisiyim. Öncelikle eklentimizin dbushell.com’daki kullanıcı deneyimini bozduğu ve yazarın nedeni bulmak için zaman ve emek harcamasına yol açtığı için gerçekten özür dilerim.
Bu amaçlanan bir durum değildi ve bunun yaşanmaması için çeşitli teknikler kullanıyoruz. Ancak yeterli olmamış ve yazı iyileştirmemiz gereken noktaları açıkça gösteriyor.
Hızlı bir düzeltme olarak dbushell.com için geçici bir istisna ekledik. Aynı zamanda uygun stil izolasyonunu garanti eden bir değişiklik üzerinde çalışıyoruz; böyle bir sorun asla yaşanmamalı
Google Translate’in web uygulamamı bozduğu benzer bir sorun var. Kullanıcı Google Translate kullanırken uygulamamın bozulduğundan şikâyet ediyor, ama aslında Google uygulama durumunu daha üst bir meta katmanda değiştirmiş oluyor. Gerçekten kötü bir pratik.
Google Translate’i tespit edip uyarı göstermeye çalışıyorum
Örneğin “[buraya tıklayarak] daha fazla bilgi görebilirsiniz” gibi bir cümleyi çevirmek gerekebilir. Başka bir dile aktarınca bağlantıyı cümlenin sonuna taşıyıp “daha fazla bilgi görmek için [buraya tıklayın]” gibi yapmak gerekebilir. Bunu yapmak için DOM öğelerini yeniden konumlandırmak gerekir ve bu da etkileşimli uygulamalarla çakışabilir.
Google Translate ekibinin müdahaleyi azaltmak için yapabileceği çok şey var, ancak yeni bir tarayıcı API’si olmadan bunu tamamen ortadan kaldırmanın zor olduğunu düşünüyorum
Mühendislik ekibine ilettim
Çalıştığım yerde de insanların bunu yapmaması beni deli ediyor. Mühendislik direktörü bile, doğrudan halletmekten daha az zaman alacak bir işi kendi bileti olarak ekliyor. Yine de “mesaj göndermek için bilet açmadım, senin yöntemine göre doğrudan o kişiye mesaj attım” sözünü sık duymak iyiye işaret
Şirkette tarayıcı uzantılarının garip şeyler yapmasından kaynaklanan çok sayıda Sentry hatası var.
Chrome’un Google Translate’i de React tabanlı siteleri bozmasıyla kötü şöhretli.
Sonunda, yeni uzantı sorunlarını tek tek yok saymaya ayırmaktan ibaret sıkıcı bir sınıflandırma işine dönüşüyor. Toplanan miktarı azaltmak için istemci tarafı filtreleme kullanıyoruz. Genel olarak arka uca göre daha gürültülü olduğundan çok daha yüksek eşikler koymak gerekiyor.
Ön yüzde çok daha fazla hata olması şaşırtıcı değil. Çünkü tipik bir arka uca kıyasla çok daha fazla istemci varyasyonunu desteklemek gerekiyor. Herkes için düzgün çalışan büyük bir web uygulaması yapmak çok zor olabiliyor.
Web’i en çok bozabilecek tek bir değişken enjekte edecek olsan ne olurdu, merak ediyorum. Aklıma şunlar geliyor:
--primary-color: transparent--serif: "Comic Sans MS"Düşmanca tarayıcı uzantılarıyla nasıl başa çıkmak gerekir?
Bunu düşünürken The Guardian’daki herhangi bir sayfayı DevTools ile açtım; birinin twitter.com’a işaret eden bir script ve iframe eklediğini gördüm.
Grammarly’yi ya da onun teknoloji modelini sevmiyorum ama aptallıkla yeterince açıklanabilen bir şeye kötü niyet atfetmek adil değil.
Ön yüz işi yapmayalı uzun zaman oldu; Grammarly uzantısı da kendi kodu da ad alanına ayrılmış özellik adları kullanmalı değil mi?
Bununla o eklentiyi ele geçirmenin mümkün olabileceğini düşünüyorum. En azından metin enjekte edilebilir gibi; hatta kullanıcının uzantıya duyduğu güveni kötüye kullanarak şık bir giriş formu da render edilebilir.
Başkasının kontrol ettiği bir belgeye öğe enjekte etmek gerçekten güvenli mi?
Yapılabilecek şey, web sitesinin içinde uzantı arayüzünü taklit etmekten ibaret; bunun için de enjekte etmeye gerek yok. Tasarımı kopyalamak yeterli.