Pixelstealing and history-stealing through floating-point timing side channel with SVG filters (CVE-2017-5407)¶
Lighting matematiği floating point kullanan Firefox SVG filter'ları subnormal (denormal) operand'larda çok daha yavaş çalıştı, dolayısıyla pixel-başına render timing'i cross-origin pixel'lerin rengini sızdırdı — same-origin-policy bypass'ını ve history sniffing'i mümkün kıldı.
Mechanism¶
Bug sınıfı / invariant
Birçok CPU'da subnormal (denormal) değerler üzerindeki floating-point operasyonları normal değerlere göre dramatik biçimde daha yavaştır — public literatürde raporlanan timing farkları kabaca bir büyüklük mertebesi veya daha fazlasına ulaşır. Lighting filter'ları gibi SVG filter'ları pixel-başına floating-point aritmetiği yapıyordu.
İhlal edilen invariant: render süresi secret pixel içeriğine bağlı olmamalıdır.
Burada bağlıydı. Bazı input renkleri için ara değerleri subnormal aralığa süren
ama diğerleri için sürmeyen filter parametreleri (ör. minik bir surfaceScale)
seçerek, bir attacker bir pixel'i render etmenin wall-clock süresini o pixel'in
değerine bağımlı hale getirir.
SVG filter'ları bir cross-origin iframe'e uygulanabildiği için, bu timing'i ölçmek attacker'ın okumasına izin verilmeyen pixel'leri sızdırır — bir same-origin policy ihlali. Browser'ın visited-link renklendirmesine uygulandığında aynı primitive bir URL'in kullanıcının history'sinde olup olmadığını açığa çıkarır (history sniffing). Bu, cache-tabanlı Pixel Thief saldırısının floating-point atasıdır ve Paul Stone'un 2013 SVG-filter pixel-stealing çizgisini sürdürür.
Walkthrough¶
Public Mozilla bug 1336622 / CVE-2017-5407'den kavramsal yeniden üretim.
-
Victim içeriğini göm. Bir cross-origin page'i (veya stillenmiş bir visited link'i) attacker page'inin altındaki bir iframe'e yerleştir.
-
Timing'e duyarlı bir filter uygula. floating-point (non-fixed-point) kod yolunu kullanan bir SVG filter uygula ki bazı pixel renkleri için subnormal operand'lar oluşsun.
-
Yükselt ve zamanla. Tek bir pixel'in rengi toplam render süresine hâkim olacak şekilde tekrar tekrar render et / filter'ı istifle, sonra render süresini yüksek çözünürlüklü bir timer ile ölç (ör.
requestAnimationFrameritmi üzerinden). Yavaş render => subnormal yol => bir pixel değeri; hızlı => başka bir değer. -
Pixel'leri / history'yi recover et. Cross-origin görsel içeriği yeniden inşa etmek için hedef bölgeyi pixel pixel tara, ya da tarama history'sini sniff etmek için visited-vs-unvisited link render'ını prob'la.
Warning
Kavramsal katalog girdisi; tam parametreler ve timing eşikleri atlanmıştır.
Detection¶
- Page sezgileri: yüksek çözünürlüklü render-timing döngüleri çalıştırırken cross-origin iframe'lere SVG lighting filter uygulayan güvenilmeyen page'ler.
- Davranışsal telemetri: filtrelenmiş bir subtree'nin frame timing'ine
senkronize tekrarlı zorlanmış yeniden render'ları; anormal
performance.now()/requestAnimationFrameölçüm desenleri. - Büyük ölçüde bir browser-içi meseledir; host EDR'nin görünürlüğü azdır. Tespit en iyi browser güvenlik telemetrisi ve content policy ile ele alınır.
Mitigation¶
- Vendor düzeltmesi (Firefox 52 / ESR 45.8, 2017): etkilenen lighting filter matematiğini floating point'ten fixed-point aritmetiğe çevir, subnormal-bağımlı timing'i tamamen kaldır.
- Cross-origin filtreleme'yi kısıtla: cross-origin pixel'leri geri okuyan SVG filter'larını yasakla — yapısal SOP düzeltmesi.
- Timer hardening: ölçüm primitive'ini engellemek için timer çözünürlüğünü düşür / jitter ekle.
- History-sniffing savunmaları: visited ve unvisited link render'ı arasındaki gözlemlenebilir farkları minimize et.
- Hardware notu: flush-to-zero / denormals-are-zero modları subnormal yavaşlamayı FPU seviyesinde kaldırır, ancak browser düzeltmesi buna dayanmadı.