2 puan yazan GN⁺ 2025-03-31 | 1 yorum | WhatsApp'ta paylaş
  • 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

 
GN⁺ 2025-03-31
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

    • Benzer bir durum. 1Password, başka eklentilerin içerik script’lerinden Chrome yan panel arayüzünü açma işlevini hâlâ bozuyor. Olayın kullanıcı etkileşiminden geldiğini gösteren güven bayrağını bozuyor.
      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

    • Asıl sinir bozucu olan şu: 5-6 ay önce bir mülakatta, 2014’te CTO ve baş geliştirici olarak çalıştığım Instagram/markalaşma startup’ından bahsettim. O dönemde CSS sınıflarının ve JavaScript nesnelerinin düzgün şekilde ad alanlarına ayrılmasını sağlayan bir build sistemi kurduğumu, çakışma olasılığını ortadan kaldırdığımı ve üçüncü taraf müşteri sitelerinde hangi widget’ların bulunduğuna göre tam olarak hangi script’lerin yüklenmesi gerektiğini yönettiğimi anlattım.
      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ş
    • Ad alanı ayırma yalnızca başkaları için değil, kendiniz için de kullanışlıdır. Önceki işimde kullanıcıya görünmeyen tarayıcı otomasyonu geliştirmiştik; eklenti bile değildi ama yine de ad alanı ayırmak faydalıydı.
      Bizim eklediklerimizle zaten var olanları net biçimde ayırt edebiliyor ve olası çakışmaları önleyebiliyorduk
    • Frontend alanından ayrılalı biraz oldu; bugünlerde CSS ad alanı ayırma genelde nasıl ele alınıyor?
    • Daha iyisi Shadow DOM kullanmak
  • 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

    • Böyle şeyleri önemseyen çalışma arkadaşlarım olduğu için kendimi oldukça şanslı hissediyorum. Toplantıdaki bazı kişilerin belirli eklentiler veya çeşitli yapay zeka yardımcıları yüklediği açıkça görülüyorsa toplantıyı durdurduğumuz oldu.
      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

    • İki gün önceki örnekle ilgili olabilir: https://www.pewresearch.org/decoded/2025/03/21/how-a-glitch-... / https://news.ycombinator.com/item?id=43441880
    • Google Translate’in müdahalesi can sıkıcı, ama mevcut tarayıcı araçlarıyla aslında başka türlü davranmasının zor olduğunu düşünü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

    • Böyle tek satırlık düzeltmelerin backlog cehenneminde uzun süre bekletilmesi epey sinir bozucu. Geliştiricinin “bilet yazmaktan hızlı, şimdi düzeltelim gitsin” dediği bir şirkette çalışmak isterim.
      Ç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.

    • Bu yalnızca basit bir gürültü değil. Kullanıcılar gerçekten de bu yüzden çökme veya başka sorunlar yaşıyor. Google Translate uzantısının React ve diğer web uygulamalarına müdahalesi hakkında ayrıntılı bir yazı var: https://martijnhols.nl/blog/everything-about-google-translat...
      Ö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.
    • “Object captured as exception” hatasından mı bahsediyorsun? Sentry’nin hiçbir yönlendirme vermediği o hataysa, biz bunu doğrudan istemci tarafında filtreliyoruz.
  • 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?

    • Yönettiğim topluluk web sitesinde en sevdiğim şikâyet bu. “İlan sayfasında fotoğraflar görünmüyor.” Reklam engelleyici kullanıyor musunuz? “Evet.” Reklam engelleyicinin ne yaptığını sanıyorsunuz...
    • Sayfa DOM’unun geçerli durumunu tanımlayıp, sayfa yüklemesi bittikten birkaç saniye sonra “düşmanca” öğeleri ve CSS stillerini tarayıp silebilmek mümkün olabilir gibi.
      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.
    • Bu durumda ‘düşmanca’ ifadesinin biraz aşırı olduğunu düşünüyorum. ‘Yetersizlik’ yeterli olur. Gerçi hece sayısı daha fazla.
      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?
    • Bu noktada tarayıcı uzantılarını hiç kurmuyorum.
    • Kaldırsan olmaz mı?
  • 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?

    • Nasıl çalışacağını anlamıyorum. Onlar senin sayfana CSS enjekte ediyor, ama web sitesi uzantı arayüzüne bir şey enjekte edemez.
      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.