Web panosu ve farklı veri türlerini saklama biçimleri
(alexharri.com)- Web panosu, bir kez kopyalanan veriyi bile birden çok MIME temsiliyle birlikte saklayarak, her uygulamanın yalnızca ihtiyaç duyduğu biçimi seçip yapıştırabilmesini sağlar
- async Clipboard API, ağırlıklı olarak
text/plain,text/html,image/pngile sınırlıdır;application/jsongibi özel türler güvenlik nedeniyle yazma sırasında reddedilir - Eski Clipboard Events API, rastgele tür dizeleriyle çalışabilir; ancak gerçek sistem panosu yalnızca güvenilir kullanıcı etkinlikleri içinde değiştirilebilir
- Google Docs,
execCommand("copy")ile güvenilir bir copy etkinliği oluşturur; Figma ise tarayıcı ile yerel uygulama arasındaki kopyalamayı yönetmek için özel verileri base64 HTML özniteliklerine koyar - Web Custom Formats,
"web "önekiyle async Clipboard API’de özel türlerin önünü açar; ancak Chromium tabanlı tarayıcılar ve güncellenmiş yerel uygulamalar gerekir
Web panosunun temel modeli
- Pano, tek bir kopyalama işlemi için birden çok temsili (representation) MIME türleriyle birlikte saklayabilir
text/plain: düz metintext/html: HTMLimage/png: PNG görüntüsü
- Google Docs, bağlantılar, yazı boyutu ve renk gibi biçimlendirmeyi korumak için
text/htmltemsilini okur - VS Code gibi yalnızca kaynak metne ihtiyaç duyan uygulamalar için
text/plaintemsilini okumak yeterlidir
async Clipboard API’nin tür sınırlaması
navigator.clipboard.read(), pano öğesinintypesdeğerlerini kontrol ettikten sonragetType("text/html")gibi belirli bir temsili okurnavigator.clipboard.write(), MIME türünü anahtar olarak kullanan birClipboardItemiçine birden çokBlobkoyup bunları tek seferde yazabilirapplication/jsonbirClipboardItemolarak yazılmaya çalışıldığındaType application/json not supported on writeistisnası oluşur- W3C Clipboard şartnamesi,
text/plain,text/html,image/pngdışındaki türlerinwritesırasında reddedilmesini öngörür application/json, 2012’den 2021’e kadar zorunlu veri türleri listesinde yer alıyordu; ancak w3c/clipboard-apis#155 ile kaldırıldı- Değişiklikten önce zorunlu veri türleri okuma için 16, yazma için 8 adetti
- Tarayıcılar güvenlik kaygıları nedeniyle birçok zorunlu türü desteklemediği için liste küçültüldü
- Şartname, güvenilmeyen betiklerin yerel yazılım açıklarını tetikleyebilecek verileri panoya koyabileceği konusunda uyarır ve bu nedenle izin verilen türlerin sınırlandırıldığını belirtir
Clipboard Events API ve isTrusted
ClipboardEvent, copy, cut, paste etkinliklerinde oluşur veclipboardDataözelliği üzerinden birDataTransfernesnesi sağlar- copy etkinliğinde
e.clipboardData.setData("text/plain", "..."),setData("text/html", "...")ile veri yazılabilir - paste etkinliğinde
e.clipboardData.getData("text/html")ile HTML temsili okunabilir clipboardData.setData("application/json", json)istisna fırlatmaz; paste işleyicisinde deapplication/jsontürü ve JSON dizgesi görülebilirclipboardData, async Clipboard API’den çok daha eski bir arayüzdür- async Clipboard API, 2017’de şartnameye eklendi
clipboardData,setData,getData2006 tarihli W3C taslağında zaten yer alıyordu- Bu taslak, Internet Explorer’da uygulanmış işlevleri büyük ölçüde yansıtıyordu
- Internet Explorer 4, 1997’de yayımlandığı için
clipboardDataarayüzünün yazının kaleme alındığı an itibarıyla en az 26 yıllık bir özellik olduğu söylenebilir
- MIME türleri 2011 şartnamesinden itibaren geldi; ancak
setData()için tür argümanı olarak herhangi bir dizge kullanabilme özelliği bugün de korunuyor Event.isTrusted, etkinlik yalnızca kullanıcı aracısı tarafından oluşturulduğundatrueolan salt okunur bir özelliktir- Kullanıcının Command+C’ye basmasıyla oluşan copy etkinliğinde
isTrusteddeğeritrueolur dispatchEvent()ile oluşturulan sentetik etkinliklerdeisTrusteddeğerifalseolur
- Kullanıcının Command+C’ye basmasıyla oluşan copy etkinliğinde
- Sentetik copy/cut etkinlikleri sistem panosunu değiştiremez; sentetik paste etkinlikleri de gerçek sistem panosu verisine erişemez
- Bu nedenle Clipboard Events API rastgele türlerle çalışabilse de gerçek panoyla etkileşim, kullanıcı aracısının oluşturduğu copy/paste etkinlik işleyicileriyle sınırlıdır
Copy düğmesinde özel tür yazma
- Google Docs’un sağ tık menüsündeki Copy düğmesi panoya üç temsil yazar
text/plaintext/htmlapplication/x-vnd.google-docs-document-slice-clip+wrapped
- Üçüncü temsil, JSON verisi taşıyan özel bir türdür ve yalnızca async Clipboard API ile yazılamaz
- Google Docs, Copy düğmesine tıklandığında
document.execCommand("copy")çağırır execCommand("copy"), kullanıcı kopyalama komutunu çalıştırmış gibi programatik olarak güvenilir bir copy etkinliği oluşturabilir- Safari’de
execCommand("copy")çağrısının copy etkinliği oluşturabilmesi için etkin bir seçim alanı gerekir- Boş olmayan bir input’u DOM’a ekleyip seçtikten sonra
execCommand("copy")çağırıp kaldırarak seçim alanı oluşturulabilir
- Boş olmayan bir input’u DOM’a ekleyip seçtikten sonra
Paste düğmesinde tarayıcı ve OS farkları
- Google Docs’un Paste düğmesi macOS’te eklenti kurulmasını isterken, Windows dizüstü bilgisayarda çalışıyordu
- Paste komutu desteği
document.queryCommandSupported("paste")ile kontrol edilebilir- macOS’te Chrome ve Firefox
false, Safaritruedöndürür - Windows’ta Chrome ve Edge
true, Firefoxfalsedöndürür
- macOS’te Chrome ve Firefox
- Safari, yapıştırma işlemini onaylatan bir istem göstererek web sitesinin panoyu okuduğunu açıkça gösterir
- Chrome’un Windows’ta
execCommand("paste")e izin verip macOS’te izin vermemesinin nedeni doğrulanmamıştır - Google Docs,
execCommand("paste")kullanılamadığında async Clipboard API’ye geri düşmez- async Clipboard API ile
application/x-vnd.google-[...]temsili okunamaz - HTML temsilinde dahili ID bulunur
- async Clipboard API ile
Figma’nın HTML tabanlı kopyalama-yapıştırması
- Figma’nın Copy düğmesi panoya
text/plainvetext/htmlolmak üzere iki temsil yazar - HTML temsilinde iki boş
spanvardır ve bunların her biridata-metadata,data-bufferözniteliklerine sahiptir data-metadata, base64 ile kodlanmış bir JSON dizgesidir; kodu çözüldüğündefileKey,pasteID,dataTypegibi değerler çıkardata-buffer, yalnızca boş bir frame kopyalansa bile yaklaşık 26.000 karakterdir ve uzunluğunun kopyalanan içerik miktarına göre doğrusal arttığı görülürdata-bufferbase64’ten çözüldüğündefig-kiwiile başlayan ikili veri ortaya çıkar; bu Kiwi message format biçimidir- Kiwi, Figma’nın kurucu ortaklarından ve eski CTO’su Evan Wallace tarafından oluşturulmuş bir biçimdir
.figdosyalarının kodlanmasında kullanılır
- Evan Wallace’ın yayımladığı
.figfile parser kullanılarakdata-bufferbir.figdosyasına dönüştürülüp incelenebilir - Figma, küçük bir Figma dosyası oluşturur, bunu base64 ile kodlar ve boş HTML
spanöğesinindata-bufferözniteliğine koyarak panoda saklar
HTML temsili kullanmanın nedeni
- Windows, macOS ve Linux, panoya veri yazmak için birbirinden farklı OS biçimleri sağlar
- Windows, HTML için
CF_HTMLsağlar - macOS,
NSPasteboard.PasteboardType.htmlsağlar
- Windows, HTML için
- Düz metin, HTML ve PNG görüntüleri birçok OS’te standart biçimlere eşlenebilir
application/foo-bargibi rastgele türler, OS panosunun ortak biçimleriyle pek uyumlu değildir- Tarayıcılar bu tür özel temsilleri OS’in ortak pano biçimlerine yazmaz; tarayıcıya özgü özel pano biçimlerinin içinde saklar
- Bunun sonucunda özel türler tarayıcı sekmeleri arasında kopyalanıp yapıştırılabilir
- Uygulamalar arasında kopyalanıp yapıştırılamaz
text/htmlkullanıldığında OS’in ortak pano biçimine eşlenir ve diğer uygulamalar tarafından daha kolay okunur- Figma,
text/htmlkullanarak tarayıcıdakifigma.comile yerel Figma uygulaması arasında öğelerin kopyalanıp yapıştırılabilmesini sağlar
Tarayıcıya göre özel veri saklama biçimleri
- macOS’te bir copy etkinliği içinde
text/plain,text/html,application/json,foo bar bazyazılıp Pasteboard Viewer ile kontrol edildiğinde, tarayıcıların saklama biçimleri farklıdır - Chrome, Pasteboard’a dört öğe ekler
public.html: HTML temsilipublic.utf8-plain-text: düz metin temsiliorg.chromium.web-custom-data: özel temsilorg.chromium.source-url: kopyalamanın yapıldığı web sayfasının URL’si
- Firefox da
public.html,public.utf8-plain-textoluşturur; ancak özel veriyiorg.mozilla.custom-clipdataiçine yazar- Chrome’un aksine kaynak URL’yi saklamaz
- Safari de
public.html,public.utf8-plain-textoluşturur ve özel veriyicom.apple.WebKit.custom-pasteboard-dataiçine yazar- Bu öğenin içinde düz metin ve HTML dahil tüm temsil listesi ile kaynak URL de saklanır
- Safari, yalnızca kaynak URL’nin alan adı aynı olduğunda tarayıcı sekmeleri arasında özel tür kopyalama-yapıştırmaya izin verir
- Chrome ve Firefox’ta aynı kısıtlama görülmez
Raw Clipboard Access ve Web Custom Formats
- Raw Clipboard Access, 2019’da önerilen bir API’ydi ve web uygulamalarına yerel OS panosuna ham okuma-yazma erişimi sağlamayı amaçlıyordu
- Raw Clipboard Access, web uygulamalarının az sayıda biçimle sınırlı olması nedeniyle Figma ve Photopea’nın çoğu görüntü biçimiyle birlikte çalışmakta zorlanması sorununu ele alıyordu
- Bu öneri, yerel uygulamalarda uzaktan kod çalıştırma gibi güvenlik kaygıları nedeniyle ilerlemedi
- Web Custom Formats, async Clipboard API’de özel türler yazmaya yönelik bir öneridir; Chromium bunu 2022’de uygulamaya aldı
- Web Custom Formats, MIME türünün başına
"web "eklenerek kullanılır- Örnek:
web application/json - Okurken de async Clipboard API’nin
read()vegetType("web application/json")kullanılır
- Örnek:
- Web Custom Formats, yerel OS panosuna iki tür veri yazar
- Veri türleri ile pano öğesi adları arasındaki eşleme
- Her veri türü için pano öğesi
- macOS’te eşleme
org.w3.web-custom-format.mapiçinde saklanır- Örnek:
"application/json": "org.w3.web-custom-format.type-0"
- Örnek:
org.w3.web-custom-format.type-[index]öğelerinde Blob’un ham verisi bulunur- Bu yöntem, web uygulamalarının istedikleri OS pano biçimine doğrudan ham veri yazmasını engelleyerek Raw Clipboard Access’in güvenlik sorunlarından kaçınır
- Buna karşılık, eski yerel uygulamalarla güncelleme olmadan birlikte çalışmak hedeflenmez
- Yerel uygulamaların Web Custom Formats biçimini okuyacak şekilde güncellenmesi gerekir
- Web Custom Formats, 2022’den beri Chromium tabanlı tarayıcılarda kullanılabilir; ancak diğer tarayıcılar henüz uygulamamıştır
unsanitized seçeneği
- async Clipboard API ile pano okunurken tarayıcı veriyi temizleyebilir
- HTML içinden tehlikeli olabilecek script etiketlerini kaldırabilir
- zip bomb saldırılarından kaçınmak için PNG görüntüsünü yeniden kodlayabilir
read()içindekiunsanitizedseçeneği, temizlenmemiş verinin istenebilmesini sağlar- Bu seçenek şu anda yalnızca Chromium tabanlı tarayıcılarda desteklenir
- 2023 sonlarında eklendi
- Diğer tarayıcılar ileride destekleyebilir; ancak Safari için bunun pek olası görünmediğini belirten geri bildirimler vardır
Gerçekçi seçenekler
- Tüm tarayıcılarda iyi çalışan bir özel pano türü yazma yöntemi henüz yok
- Figma’nın yaptığı gibi base64 dizgesini HTML temsili içine koymak kaba bir yöntem olsa da Clipboard API’nin çeşitli kısıtlarını aşarak özel veriyi pano üzerinden aktarabilir
- Web Custom Formats, özel türleri daha güvenli ve pratik biçimde kullanmaya yönelik bir yol sunar; ancak başlıca tarayıcıların genelinde uygulanması gerekir
1 yorum
Hacker News yorumları
Güzel yazı. Mac’te Firefox ile Google Docs’a biçimlendirmeyi koruyarak/biçimlendirmesiz yapıştırma işleminin neden düzgün çalışmadığını anladım.
Google’ın panoya kendi içerik biçimini koymak için kullanımdan kaldırılmış bir API kullanıyor olması ilginç.
Özel uygulama verilerini panoya göndermenin en güvenilir yolu, Figma’nın yaptığı gibi veriyi HTML’in içine gömmek gibi görünüyor.
Alıcı uygulama desteklemediğinde HTML mesajıyla başarısızlık davranışını bile tanımlayabilmek de bir avantaj.
WordPress de bu meseleye dokunuyor. Düzenleyici modunda birden çok paragrafı kesip yapıştırırsanız işler epey bozulabilir.
Muhtemelen paragraflar aslında birbirinden farklı DIV alanları olduğu ve farklı kontrol mantıkları ile efektlerin altında bulunduğu içindir.
Ayrıca makine, benim ASCII sandığım şeyi UTF-8’e ya da ISO Latin-1’e yükseltip Clippy gibi “tırnak işaretlerini daha güzel görünenlerle değiştirdim, sonra teşekkür edersin” tarzı şeyler yapıyor; bunu hiç istemedim.
this'isteseydim 'this' yazmazdım.Eskiden öğrenciyken JavaScript kullanıcı izni olmadan panoyu okuyabiliyordu ve getpasted adlı bir web sitesi yapmıştım.
Panoyu otomatik olarak yapıştırıp herkese açık bir veritabanına yükleyen bir siteydi; doğal olarak bundan hoşlanmayanlar da oldu.
Yine de panonun her an okunabildiğini gösteren bir proje olarak fena değildi.
Pasteboard Manager[0]’ın geliştiricisi Sindre Sorhus, Actions[1] kısayol kitaplığını ve çeşitli iPhone/Mac uygulamalarını da yapan kişi. HN’de var mı bilmiyorum.
0. https://apps.apple.com/us/app/pasteboard-viewer/id1499215709
https://www.npmjs.com/~sindresorhus
Kapsam ve derinlik kombinasyonu özellikle iyi. Sistem ve tarayıcı bazlı farkları ele alırken tuzakları ve geçici çözümleri de birlikte açıklıyor.
Tarayıcıdan “özel” verileri alma konusuyla ilgili olarak, bankamın web uygulaması girişte makine adım olan aluminium’u gösterip iki faktörlü doğrulama istedi.
Bunu nasıl öğrendi bilmiyorum. Mobilden girince iki faktörlü doğrulama kodunu içeren SMS’i de görebiliyor ve otomatik yapıştırabiliyordu. Pixel+Chrome veya Linux+Chrome ortamıydı.
Makine adı daha zor. Bankaya bu bilgiyi kullanıcı adı gibi bir biçimde gerçekten verip vermediğini kontrol etmek gerekir. Hangi banka olduğunu da merak ettim.
Bu yazı, web uygulamalarının neden yerel uygulamalar kadar iyi olamayacağını iyi gösteriyor.
Web uygulamaları her zaman “güvenilmeyen” kod olduğu için yerel makinedeki kaynaklara erişimleri keyfi ve yapay biçimde kısıtlanır.
Artık script kiddie’lerin ortalıkta dolaştığı erken internet dönemi de değil, yalnızca meraklıların kullandığı bir alan da değil. Devlet bağlantılı grupların nükleer programlarını finanse etmek için kritik altyapıya fidye yazılımı saldırıları düzenlediği bir çağdayız. Yerel makinedeki keyfi kaynak erişimi tam da bu tür şeyleri mümkün kılar.
Modern tarayıcılardaki web uygulamaları doğal olarak daha güçlü bir sandbox içinde çalışır; ancak modern işletim sistemlerinde yerel uygulamalar da güvenilmeyen hedefler olarak ele alınır. Yeni bir uygulama çalıştırdığınızda, yalıtılmış uygulama veri dizininin dışına erişmeden önce bir onay penceresi çıkar.
Bu arada MacBook’ta uyarı çıkaran Chrome eklentisinin hangisi olduğunu merak ediyorum.