1 पॉइंट द्वारा GN⁺ 4 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • एक डेवलपर ने ब्राउज़र टैब आइकन favicon को पिक्सेल-बाइट स्टोरेज की तरह देखते हुए, छोटे HTML को इमेज के RGB चैनलों में रखने का प्रयोग किया
  • एन्कोडिंग में HTML के UTF-8 bytes के आगे 4-byte length header जोड़ा जाता है, और हर byte को पिक्सेल के R·G·B मानों में क्रम से लिखा जाता है
  • डेमो payload 208 bytes का है और header सहित 212 bytes का, इसलिए 3 bytes प्रति पिक्सेल के हिसाब से 71 pixels और 9×9 PNG पर्याप्त रहा
  • रिकवरी के लिए favicon इमेज को canvas पर draw करने के बाद JavaScript पिक्सेल डेटा पढ़ता है, RGB मानों को फिर से byte array में जोड़ता है और उसे HTML में decode करता है
  • सिर्फ favicon से वेबसाइट अपने-आप नहीं चलती; अलग bootstrap JavaScript चाहिए, इसलिए यह उपयोगिता से ज़्यादा एक boundary experiment जैसा है

favicon को स्टोरेज की तरह संभालने का तरीका

  • favicon ब्राउज़र टैब में दिखने वाला छोटा आइकन है, लेकिन असल में यह पिक्सेल और bytes से बनी एक image file है
  • प्रयोग की शुरुआत steganography से हुई थी, लेकिन डेमो में आइकन जैसा दिखने से ज़्यादा इसे शुद्ध स्टोरेज स्पेस की तरह इस्तेमाल करने पर फोकस है
  • स्टोर किया जाने वाला डेटा एक छोटा HTML payload है
Website in a Favicon

Everything you're reading right now was decoded from favicon pixels.

  • एन्कोडिंग प्रक्रिया सरल है
    • TextEncoder से HTML को UTF-8 bytes में बदला जाता है
    • payload की लंबाई रखने वाला 4-byte header आगे जोड़ा जाता है
    • कुछ पिक्सेल बच सकते हैं, इसलिए length header से असली payload का अंत पहचाना जाता है
    • पहला byte पहले पिक्सेल के red channel में, दूसरा byte green में, और तीसरा byte blue में स्टोर होता है
    • इसके बाद बाकी पिक्सेल भी इसी क्रम में भरे जाते हैं, और पूरा HTML डॉक्यूमेंट रंग मानों में चला जाता है
  • नतीजे की इमेज देखने में noise जैसी लगती है

आकार और रिकवरी प्रक्रिया

  • डेमो का अंतिम आकार बहुत छोटा है
    • payload: 208 bytes
    • header सहित कुल: 212 bytes
    • आवश्यक पिक्सेल: 71 pixels
    • इमेज आकार: 9×9 pixels
    • क्षमता: 239 bytes
    • उपयोग दर: 87% {p:87}
  • रिकवरी सिर्फ ब्राउज़र फीचर्स से होती है
    • favicon को इमेज के रूप में लोड किया जाता है
    • इमेज को canvas पर draw किया जाता है
    • Canvas API से सभी पिक्सेल पढ़े जाते हैं
    • RGB मानों को byte array में फिर से बनाया जाता है
    • शुरुआती 4 bytes से payload की लंबाई पढ़ी जाती है
    • payload निकाला जाता है और UTF-8 text में decode किया जाता है
  • डेमो साइट में "Render Website" बटन दबाने पर favicon पढ़ा जाता है, HTML को रिकवर किया जाता है, और फिर पेज की सामग्री बदल दी जाती है

सीमाएँ और विकल्प

  • सबसे बड़ी सीमा यह है कि favicon अकेले पूरे वेबसाइट को चला नहीं सकता
    • favicon में वेबसाइट का content होता है
    • decode करने के लिए अलग से एक छोटा JavaScript loader चाहिए
    • JavaScript के बिना favicon सिर्फ वेबसाइट content वाला PNG है
  • व्यावहारिकता कम है
    • स्टोर किया जा सकने वाला डेटा बहुत छोटा है
    • पेज को JavaScript से bootstrap करना पड़ता है
    • छोटे HTML डॉक्यूमेंट बाँटने के इससे बेहतर कई तरीके हैं
  • विकल्प के तौर पर SVG favicon में सीधे markup डालना, PNG के tEXt, zTXt, iTXt comment chunk का उपयोग, और कई resolution icons रखने वाले ico file format का उपयोग किया जा सकता है
  • डेमो साइट: https://www.timwehrle.de/labs/favicon-site/
  • इम्प्लीमेंटेशन कोड: https://github.com/timwehrle/favicon

1 टिप्पणियां

 
GN⁺ 4 시간 전
Hacker News की राय
  • पिक्सेल के रास्ते जाने के बजाय SVG favicon इस्तेमाल करके उसके अंदर सीधे markup स्टोर कर के बाद में extract किया जा सकता है, ऐसा लगता है
    favicon.svg में hello HN! जैसा content डालें, उसे SVG favicon के रूप में इस्तेमाल करें, फिर document body में extract करके चिपका दें

    • इसे “विकल्प के तौर पर क्यों नहीं करते” की बजाय “यह भी एक मज़ेदार variation है” की तरह देखना ज़्यादा सही होगा। दोनों ही मज़े, जिज्ञासा और खोजबीन के लिए tech के साथ खेलने के तरीके हैं, और पिक्सेल के अंदर स्टोर करने वाला approach Rube Goldberg machine जैसी मज़ेदार भावना देता है
    • मैं ही लेखक हूँ, और हाँ, यह तरीका ज़्यादा practical है। लेकिन मैं चाहता था कि payload XML file के अंदर छिपे text की तरह नहीं, बल्कि असली pixel data के अंदर “जीवित” रहे, इसलिए मैंने ऐसा किया :)
    • regex? उफ़। बस सही namespace में ठीक से XML encode करें और उसी तरह पढ़ लें
      या फिर SVG file को वैसे ही serve करके उसके अंदर HTML embed भी किया जा सकता है। सिद्धांत में इसे define करके use कर पाना चाहिए, लेकिन अफ़सोस कि Firefox और Chromium दोनों favicon के अंदर इसे ठीक से handle नहीं करते दिखते
    • अगर अपनी निजी सनक पर बोलूँ, तो [\s\S] को इससे छोटा और ज़्यादा सही [^] लिख सकते हैं
    • SVG में raster image को base64-encoded bytes के रूप में embed किया जा सकता है
      इसलिए experiment की एक और layer जोड़ी जा सकती है: favicon SVG हो, उसके अंदर encoded raster हो, और उन bytes के अंदर HTML encoded हो। कम से कम यह किसी दिमाग घुमा देने वाले CTF level जैसा तो बनेगा
  • बेशक यह कोई नया idea नहीं है। उदाहरण के लिए, 2000 में किसी ने deCSS को favicon में स्टोर किया था
    https://web.archive.org/web/20010408040524if_/http://decss.z...
    extraction dd bs=1 skip=2238 < favicon.ico से किया जा सकता है

  • यह कहना भी ज़रूरी नहीं कि “image decode करने के लिए अब भी एक छोटा bootstrap loader चाहिए।” HTML/PNG polyglot इस्तेमाल करें तो सब कुछ एक ही file में हो सकता है, और आजकल WebP जैसे नए formats से compression ratio भी बेहतर हो सकती है
    https://web.archive.org/web/20120801001616/http://daeken.com...

  • अगर user को कई domains पर redirect किया जाए, तो favicon cache को storage की तरह भी इस्तेमाल किया जा सकता है। इसे संभावित fingerprinting risk के रूप में पहले प्रस्तावित किया गया था[0], और अगर browser incognito mode में भी cache को भोलेपन से reuse करे, तो अलग-अलग browser profiles के बीच user tracking के लिए इसका दुरुपयोग हो सकता है
    [0]: https://www.schneier.com/blog/archives/2021/02/browser-track...

    • क्या यह पहले ही fix नहीं हो चुका, या कम से कम ज़्यादातर जगह fix नहीं हो गया?
    • मूल पोस्ट पढ़ते ही मेरे दिमाग में सहज रूप से आया, “इसे तो fingerprinting के लिए इस्तेमाल किया जा रहा होगा।” जानना दिलचस्प होगा कि anti-fingerprinting उपाय favicon और Canvas API के इस संयोजन तक भी ध्यान दे रहे हैं या नहीं
      अफ़सोस, supercookie site का link अब dead है
  • PNG में tEXt, zTXt, iTXt comment chunks होते हैं। ऊपर से बिल्कुल सामान्य image file दिखने वाली चीज़ में आप जितना चाहें उतना content ठूँस सकते हैं। हाँ, मज़ा शायद थोड़ा कम रहेगा

  • क्या timing सिर्फ़ संयोग है? अभी 1 घंटे पहले, बल्कि ठीक कहें तो इस पोस्ट से 30 मिनट पहले, मैंने ऐसी site पोस्ट की थी जो stock portfolio को URL + favicon में store करती है
    https://news.ycombinator.com/item?id=48606396

  • यह सोचने का तरीका इससे बहुत मेल खाता है: monitor भी storage है, keyboard भी storage है, और forum post भी storage है
    समय के साथ edits में Markov-स्वीकृत variations डालें तो काफ़ी storage capacity बन जाती है। ऊपर से comments कभी-कभी सामाजिक रूप से भी दिलचस्प होते हैं, तो यह dual-purpose storage बन जाता है।
    किसी का chicken casserole recipe दरअसल बहुत सोच-समझकर बनाया गया GUID handle हो सकता है, और मज़ाक-मज़ाक में ही सही, शायद वह हज़ार अलग forum posts की ओर इशारा कर रहा हो—कौन जाने। सोच रहा हूँ क्या लेखक PoC||GTFO को जानता है; यह तो पक्का Alchemist Owls की पवित्र किताब की गहराइयों में मिलने वाली तकनीक जैसी लगती है

    • code के अंदर code। पहिए के अंदर पहिया
  • इस तरह की आक्रामक, टूटी-टूटी, साफ़ तौर पर LLM-generated लगने वाली writing style की वजह से इसे पढ़ना बहुत मुश्किल था

    • कुछ महीने पहले मैंने Medium पर इसी style की शिकायत की थी। उस लेख के author ने जवाब दिया था कि अगर मानकर चला जाए कि लोग इसे छोटे smartphone screen पर पढ़ेंगे, तो यह पसंदीदा style बन जाती है। कुछ हद तक बात समझ में आती है। वह लेख या यह लेख AI-generated है या नहीं, मुझे नहीं पता
    • आधा पढ़ने तक मुझे पूरा यक़ीन था कि आख़िर में ट्विस्ट आएगा: “दरअसल यह लेख खुद इसी site के favicon में store था,” और वही इन छोटे-छोटे, कटे हुए वाक्यों को समझाएगा। जब पता चला कि ऐसा नहीं है, तो सच में निराशा हुई। मौका चूक गया
    • मुझे यह writing style पसंद आई। मैं भी कभी-कभी ऐसे ही लिखता हूँ, और अपनी writing generate करने के लिए मैंने कभी LLM का इस्तेमाल नहीं किया। काम पर भी मैं बिल्कुल इसी तरह लिख चुका हूँ
      मुझे तो लेखक बस सीधे मुद्दे पर जाता हुआ लगा। शायद वह जानता है कि text ज़्यादा हो तो लोग बस सरसरी नज़र से पढ़ने लगते हैं
    • काफ़ी समय बाद HN पर मैं AI-generated style वाली इस पहचान से सहमत नहीं हूँ। बहुत हुआ तो LLM से draft शुरू किया गया होगा, लेकिन final result काफ़ी इंसानी लगता है
      it’s/its गड़बड़ था, But. को एक-शब्द वाले sentence की तरह इस्तेमाल किया गया, HTML को uppercase में नहीं लिखा गया, और brackets के अंदर “okayy” लिखा गया। मैं लेखक की आलोचना नहीं कर रहा; बल्कि ऐसी छोटी अपूर्णताएँ दिखाती हैं कि blog post सच में इंसानी है, और इससे पढ़ना और मज़ेदार लगा
    • लेख engaging था और पढ़ने में मज़ा आया
  • इससे Inigo का real pixel coding याद आ गया: https://www.youtube.com/watch?v=FvS_DG8yIqQ
    यह Photoshop में pixels सजाकर और exe के रूप में save करके बनाई गई 256-byte intro है

  • एक मज़ेदार तथ्य: किसी भी inline SVG को favicon की तरह इस्तेमाल किया जा सकता है और HTML document के अंदर वैसे ही रखा जा सकता है
    इससे emoji को सीधे favicon की तरह इस्तेमाल करना भी संभव है। HN पर emoji दिखाई नहीं देते

    • जानकारी के लिए, ऐसा करते समय अगर आप #rrggbb color code या url(#id) links इस्तेमाल करना चाहते हैं, तो # को %23 के रूप में escape करना होगा। नहीं तो उसे URL fragment की तरह parse किया जाएगा और SVG code वहीं कट जाएगा