4 पॉइंट द्वारा GN⁺ 2024-09-02 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • वेब क्लिपबोर्ड एक बार कॉपी किए गए डेटा को कई MIME representations के साथ स्टोर कर सकता है, ताकि हर ऐप अपनी ज़रूरत के अनुसार उपयुक्त फ़ॉर्मेट चुनकर paste कर सके
  • async Clipboard API मुख्य रूप से text/plain, text/html, image/png तक सीमित है, इसलिए application/json जैसे custom types को सुरक्षा कारणों से write करने से मना किया जाता है
  • पुराना Clipboard Events API मनचाहे type strings को संभाल सकता है, लेकिन वास्तविक system clipboard केवल trusted user event के भीतर ही बदला जाता है
  • Google Docs execCommand("copy") के जरिए trusted copy event बनाता है, और Figma custom data को base64 HTML attribute में रखकर browser और native app के बीच copy को संभालता है
  • Web Custom Formats "web " prefix के साथ async Clipboard API में custom types खोलता है, लेकिन इसके लिए Chromium-आधारित browser और अपडेटेड native apps चाहिए

वेब क्लिपबोर्ड का बुनियादी मॉडल

  • क्लिपबोर्ड एक copy action के लिए कई representations को MIME type के साथ स्टोर कर सकता है
    • text/plain: सामान्य टेक्स्ट
    • text/html: HTML
    • image/png: PNG इमेज
  • Google Docs text/html representation को पढ़कर link, font size, color जैसी formatting बनाए रखता है
  • VS Code जैसे ऐप, जिन्हें केवल मूल टेक्स्ट चाहिए, सिर्फ text/plain representation पढ़ सकते हैं

async Clipboard API की type सीमाएं

  • navigator.clipboard.read() क्लिपबोर्ड item के types को जांचने के बाद getType("text/html") की तरह किसी खास representation को पढ़ता है
  • navigator.clipboard.write() MIME type को key मानने वाले ClipboardItem में कई Blob रखकर एक बार में write कर सकता है
  • अगर application/json को ClipboardItem के रूप में write करने की कोशिश करें, तो Type application/json not supported on write exception आता है
  • W3C Clipboard spec कहती है कि text/plain, text/html, image/png के अलावा बाकी types को write में reject किया जाए
  • application/json 2012 से 2021 तक required data types की सूची में था, लेकिन w3c/clipboard-apis#155 में इसे हटा दिया गया
    • बदलाव से पहले required data types की सूची में read के लिए 16 और write के लिए 8 types थे
    • browser सुरक्षा चिंताओं के कारण कई required types को support नहीं कर पाए, इसलिए सूची छोटी कर दी गई
  • spec चेतावनी देती है कि untrusted script क्लिपबोर्ड में ऐसा डेटा डाल सकती है जो local software vulnerabilities को trigger करे, इसलिए allowed types को सीमित किया जाता है

Clipboard Events API और isTrusted

  • ClipboardEvent copy, cut, paste events में बनता है और clipboardData property के जरिए DataTransfer object देता है
  • copy event में e.clipboardData.setData("text/plain", "..."), setData("text/html", "...") से डेटा लिखा जा सकता है
  • paste event में e.clipboardData.getData("text/html") से HTML representation पढ़ी जा सकती है
  • clipboardData.setData("application/json", json) exception नहीं फेंकता, और paste handler में application/json type और JSON string दोनों देखे जा सकते हैं
  • clipboardData async Clipboard API की तुलना में बहुत पुराना interface है
    • async Clipboard API को 2017 में spec में जोड़ा गया था
    • clipboardData, setData, getData 2006 के W3C draft में पहले से मौजूद थे
    • वह draft काफी हद तक Internet Explorer में implemented features को दर्शाता था
    • Internet Explorer 4 1997 में जारी हुआ था, इसलिए clipboardData interface को इस लेख के समय के हिसाब से कम से कम 26 साल पुरानी सुविधा माना जा सकता है
  • 2011 की spec से MIME types शामिल हुए, लेकिन setData() के type argument में कोई भी string देने की क्षमता आज भी बनी हुई है
  • Event.isTrusted एक read-only property है, जो event के user agent द्वारा पैदा होने पर ही true होती है
    • जब user Command+C दबाता है, तो copy event का isTrusted true होता है
    • dispatchEvent() से बनाए गए synthetic event का isTrusted false होता है
  • synthetic copy/cut events system clipboard को modify नहीं कर सकते, और synthetic paste events वास्तविक system clipboard data तक पहुंच नहीं सकते
  • इसलिए Clipboard Events API arbitrary types को संभाल सकता है, लेकिन वास्तविक clipboard interaction केवल user agent द्वारा पैदा किए गए copy/paste event handler के भीतर सीमित रहती है

Copy बटन से custom type write करना

  • Google Docs के right-click menu में Copy बटन क्लिपबोर्ड पर तीन representations लिखता है
    • text/plain
    • text/html
    • application/x-vnd.google-docs-document-slice-clip+wrapped
  • तीसरी representation JSON data रखने वाला custom type है, और इसे केवल async Clipboard API से write नहीं किया जा सकता
  • Google Docs Copy बटन पर click होने पर document.execCommand("copy") को call करता है
  • execCommand("copy") इस तरह programmatically trusted copy event trigger कर सकता है जैसे user ने copy command चलाई हो
  • Safari में execCommand("copy") से copy event trigger करने के लिए active selection range चाहिए
    • इसके लिए DOM में non-empty input जोड़कर उसे select किया जाता है, फिर execCommand("copy") call करके उसे हटा दिया जाता है

Paste बटन में browser·OS का अंतर

  • Google Docs का Paste बटन macOS पर extension install करने को कहता था, लेकिन Windows laptop पर काम कर रहा था
  • document.queryCommandSupported("paste") से paste command support की जांच की जा सकती है
    • macOS पर Chrome और Firefox false, Safari true लौटाते हैं
    • Windows पर Chrome और Edge true, Firefox false लौटाते हैं
  • Safari paste action की पुष्टि करने वाला prompt दिखाता है, जिससे साफ़ पता चलता है कि website क्लिपबोर्ड पढ़ रही है
  • Chrome Windows पर execCommand("paste") क्यों allow करता है और macOS पर क्यों नहीं, यह स्पष्ट नहीं है
  • जब Google Docs execCommand("paste") का उपयोग नहीं कर सकता, तब वह async Clipboard API पर fallback नहीं करता
    • async Clipboard API से application/x-vnd.google-[...] representation नहीं पढ़ी जा सकती
    • HTML representation में internal ID शामिल होती है

Figma का HTML-आधारित copy·paste

  • Figma का Copy बटन क्लिपबोर्ड पर text/plain और text/html दो representations लिखता है
  • HTML representation में दो खाली span होते हैं, जिनमें क्रमशः data-metadata, data-buffer attributes होते हैं
  • data-metadata base64-encoded JSON string है; decode करने पर fileKey, pasteID, dataType जैसे मान मिलते हैं
  • data-buffer खाली frame कॉपी करने पर भी लगभग 26,000 characters का होता है, और कॉपी किए गए content की मात्रा के साथ इसकी लंबाई रैखिक रूप से बढ़ती दिखती है
  • data-buffer को base64 decode करने पर fig-kiwi से शुरू होने वाला binary data मिलता है, जो Kiwi message format है
    • Kiwi, Figma के सह-संस्थापक और पूर्व CTO Evan Wallace द्वारा बनाया गया फ़ॉर्मेट है
    • इसका उपयोग .fig file encoding में होता है
  • Evan Wallace द्वारा साझा किए गए .fig file parser का उपयोग करके data-buffer को .fig file में बदलकर देखा जा सकता है
  • Figma एक छोटी Figma file बनाता है, उसे base64 में encode करता है, और फिर खाली HTML span के data-buffer attribute में रखकर क्लिपबोर्ड में स्टोर करता है

HTML representation का उपयोग क्यों किया जाता है

  • Windows, macOS, Linux क्लिपबोर्ड पर डेटा write करने के लिए अलग-अलग OS formats देते हैं
    • Windows HTML के लिए CF_HTML देता है
    • macOS NSPasteboard.PasteboardType.html देता है
  • सामान्य टेक्स्ट, HTML, PNG image जैसी चीज़ें कई OS में standard formats से map की जा सकती हैं
  • application/foo-bar जैसे arbitrary types OS clipboard के common formats से अच्छी तरह मेल नहीं खाते
  • browser ऐसे custom representations को OS के common clipboard format में write नहीं करते, बल्कि browser-specific custom clipboard formats में स्टोर करते हैं
    • इसका नतीजा यह है कि custom types browser tabs के बीच copy-paste हो सकते हैं
    • लेकिन अलग applications के बीच copy-paste नहीं हो पाते
  • text/html का उपयोग करने पर इसे OS के common clipboard format से map किया जा सकता है, इसलिए दूसरी applications इसे आसानी से पढ़ सकती हैं
  • Figma text/html का उपयोग करके browser के figma.com और native Figma app के बीच elements को copy-paste कर सकता है

browser के अनुसार custom data store करने के तरीके

  • macOS में copy event के भीतर text/plain, text/html, application/json, foo bar baz लिखने के बाद Pasteboard Viewer में देखने पर हर browser का store करने का तरीका अलग दिखता है
  • Chrome Pasteboard में चार items जोड़ता है
    • public.html: HTML representation
    • public.utf8-plain-text: सामान्य टेक्स्ट representation
    • org.chromium.web-custom-data: custom representation
    • org.chromium.source-url: जिस web page पर copy हुई उसका URL
  • Firefox भी public.html, public.utf8-plain-text बनाता है, लेकिन custom data को org.mozilla.custom-clipdata में लिखता है
    • Chrome के विपरीत, यह source URL स्टोर नहीं करता
  • Safari भी public.html, public.utf8-plain-text बनाता है और custom data को com.apple.WebKit.custom-pasteboard-data में लिखता है
    • इस item के भीतर सामान्य टेक्स्ट और HTML सहित पूरी representation list और source URL भी स्टोर होते हैं
  • Safari केवल तब browser tabs के बीच custom type copy-paste की अनुमति देता है जब source URL का domain एक जैसा हो
    • Chrome और Firefox में ऐसी सीमा दिखाई नहीं देती

Raw Clipboard Access और Web Custom Formats

  • Raw Clipboard Access 2019 में प्रस्तावित API था, जिसका उद्देश्य web applications को native OS clipboard के raw read/write access देना था
  • Raw Clipboard Access उस समस्या को संबोधित करता था कि web applications कुछ ही formats तक सीमित हैं, जिससे Figma और Photopea के लिए ज़्यादातर image formats के साथ interoperability मुश्किल होती है
  • native applications में remote code execution जैसी सुरक्षा चिंताओं के कारण यह प्रस्ताव आगे नहीं बढ़ा
  • Web Custom Formats async Clipboard API में custom types write करने का प्रस्ताव है, और Chromium ने इसे 2022 में implement किया
  • Web Custom Formats MIME type के आगे "web " prefix लगाकर उपयोग करता है
    • उदाहरण: web application/json
    • पढ़ने के लिए भी async Clipboard API का read() और getType("web application/json") इस्तेमाल होता है
  • Web Custom Formats native OS clipboard में दो तरह का डेटा लिखता है
    • data type और clipboard item name के बीच mapping
    • हर data type के लिए clipboard item
  • macOS में mapping org.w3.web-custom-format.map में स्टोर होती है
    • उदाहरण: "application/json": "org.w3.web-custom-format.type-0"
  • org.w3.web-custom-format.type-[index] item में Blob का unsanitized data रखा जाता है
  • यह तरीका web applications को अपनी पसंद के OS clipboard format में unsanitized data सीधे write करने से रोकता है, जिससे Raw Clipboard Access की सुरक्षा समस्या से बचा जा सके
  • इसके बदले, बिना update किए legacy native applications के साथ interoperability इसका लक्ष्य नहीं है
    • native applications को Web Custom Formats format पढ़ने के लिए update करना होगा
  • Web Custom Formats 2022 से Chromium-आधारित browsers में उपलब्ध है, लेकिन दूसरे browsers ने अभी तक इसे implement नहीं किया है

unsanitized option

  • async Clipboard API से क्लिपबोर्ड पढ़ते समय browser डेटा को sanitize कर सकता है
    • HTML में संभावित रूप से खतरनाक script tags हटाए जा सकते हैं
    • zip bomb attack से बचने के लिए PNG images को फिर से encode किया जा सकता है
  • read() का unsanitized option unsanitized data मांगने की सुविधा देता है
  • यह option फिलहाल केवल Chromium-आधारित browsers में supported है
    • इसे 2023 के अंत में जोड़ा गया था
    • दूसरे browsers भविष्य में इसे support कर सकते हैं, लेकिन Safari के बारे में मिली प्रतिक्रिया के आधार पर इसकी संभावना कम लगती है

व्यावहारिक विकल्प

  • ऐसा कोई तरीका अभी नहीं है जो सभी browsers में custom clipboard types को अच्छी तरह write कर सके
  • Figma की तरह base64 string को HTML representation के भीतर रखना थोड़ा असुविधाजनक है, लेकिन यह Clipboard API की कई सीमाओं को पार करके custom data को क्लिपबोर्ड के जरिए पहुंचा सकता है
  • Web Custom Formats custom types को अधिक सुरक्षित और व्यावहारिक तरीके से इस्तेमाल करने की दिशा देता है, लेकिन इसके लिए प्रमुख browsers में व्यापक implementation चाहिए

1 टिप्पणियां

 
GN⁺ 2024-09-02
Hacker News की टिप्पणियाँ
  • अच्छा लेख है। समझ आया कि Mac के Firefox में Google Docs पर formatting के साथ/बिना paste करना ठीक से क्यों काम नहीं करता था
    यह दिलचस्प है कि Google clipboard में अपना खुद का content format डालने के लिए deprecated API का इस्तेमाल कर रहा है

    • शायद किसी दिन Google Web को आधिकारिक web का fork घोषित करना पड़े
  • custom app data को clipboard में भेजने का सबसे भरोसेमंद तरीका Figma की तरह HTML के अंदर data embed करना लगता है
    इसका एक फायदा यह भी है कि receiving app support न करे तो HTML message के जरिए failure behavior तक define किया जा सकता है

  • WordPress भी इस समस्या से जूझता है। editor mode में कई paragraphs को cut-paste करने पर चीजें बुरी तरह बिगड़ सकती हैं
    शायद इसलिए कि paragraphs वास्तव में अलग-अलग DIV areas होते हैं, और अलग-अलग control logic व effects के तहत होते हैं
    फिर machine उस चीज़ को, जिसे मैं ASCII मानता था, UTF-8 या ISO Latin-1 में upgrade कर देती है, और Clippy की तरह “मैंने quotes को ज्यादा सुंदर बना दिया है, बाद में धन्यवाद देना” जैसा व्यवहार करती है, जबकि मैंने ऐसा कभी नहीं चाहा। अगर मुझे `this' चाहिए होता, तो मैं 'this' नहीं टाइप करता

  • पहले जब मैं student था, तब JavaScript user की सहमति के बिना clipboard पढ़ सकता था, और मैंने getpasted नाम की website बनाई थी
    वह site clipboard को अपने-आप paste करके public database में डाल देती थी, और जाहिर है कुछ लोगों को यह पसंद नहीं था
    फिर भी यह बताने वाले project के तौर पर ठीक था कि clipboard को कभी भी पढ़ा जा सकता है

    • लोगों को यह जानकर हैरानी होगी कि Windows 11 में default रूप से Clipboard History / Cloud Clipboard के जरिए clipboard का सारा data Microsoft servers पर भेजा जाता है
  • Pasteboard Manager[0] के निर्माता Sindre Sorhus ने Actions[1] shortcuts library और कई iPhone·Mac apps भी बनाए हैं। पता नहीं वे HN पर हैं या नहीं
    0. https://apps.apple.com/us/app/pasteboard-viewer/id1499215709

    1. https://apps.apple.com/us/app/actions/id1586435171
    • वह नाम जाना-पहचाना है। उन्होंने काफी अच्छे NPM packages भी public किए हुए हैं
      https://www.npmjs.com/~sindresorhus
  • scope और depth का combination खास तौर पर अच्छा है। system·browser के हिसाब से फर्क भी cover करता है और साथ में pitfalls और workarounds भी समझाता है

    • लेख में जरूरत से ज्यादा details और tangents कम करने की कोशिश करता आया हूँ। लेख लंबा है, लेकिन इस बार balance अच्छा बैठा लगता है, यह राहत की बात है
  • browser से “private” data लेने की बात से जुड़ा एक अनुभव: मेरे bank web app ने login के समय मेरा hostname, aluminium, दिखाया और 2-factor authentication मांगा
    पता नहीं उसने यह कैसे जाना। mobile से access करने पर वह 2-factor authentication code वाला SMS भी देख सकता था और उसे अपने-आप paste कर सकता था। environment Pixel+Chrome या Linux+Chrome था

    • 2-factor authentication code शायद Chrome feature होने की संभावना ज्यादा है। Safari भी SMS verification code को autocomplete suggestion के रूप में दिखाता है, और Android पर Chrome शायद सीधे auto-fill कर सकता है
      hostname ज्यादा मुश्किल मामला है। यह देखना होगा कि आपने bank को username जैसी किसी form में वह जानकारी सचमुच कभी नहीं दी थी या नहीं। यह भी जानना चाहूँगा कि कौन सा bank था
  • यह लेख अच्छी तरह दिखाता है कि web apps native apps जितने अच्छे क्यों नहीं बन सकते
    web apps हमेशा “untrusted” code होते हैं, इसलिए local machine के resources तक access arbitrary और artificially limited रहता है

    • default रूप से भरोसा न करना एक feature है। जब तक user हमेशा सतर्क रहने वाला highly trained security professional न हो, उसके लिए खुद को बचाना मुश्किल है
      अब वह शुरुआती internet का दौर नहीं है जब script kiddies उपद्रव करते थे, और न ही यह सिर्फ geeks की जगह है। यह ऐसा दौर है जब सरकार से जुड़े संगठन nuclear program को fund करने के लिए critical infrastructure पर ransomware attacks करते हैं। local machine के arbitrary resources तक access ही ऐसी चीजों को संभव बनाता है
      modern browsers में web apps स्वाभाविक रूप से ज्यादा मजबूत sandbox के अंदर होते हैं, लेकिन modern operating systems में native apps को भी untrusted माना जाता है। नया app चलाने पर isolated app data directory के बाहर access करने से पहले confirmation dialog आता है
  • वैसे MacBook पर warning दिखाने वाला Chrome extension कौन सा था, यह जानने की उत्सुकता है