- Seorang pengembang melakukan eksperimen dengan melihat favicon, ikon tab browser, sebagai penyimpanan byte berbasis piksel, lalu menaruh HTML kecil ke dalam kanal RGB gambar
- Proses encoding dilakukan dengan menambahkan header panjang 4 byte di depan byte UTF-8 HTML, lalu menulis setiap byte secara berurutan ke nilai R·G·B piksel
- Payload demo berukuran 208 byte, dan menjadi 212 byte termasuk header, sehingga cukup dengan 71 piksel yang masing-masing menyimpan 3 byte serta PNG 9×9
- Untuk memulihkan data, gambar favicon digambar ke canvas lalu JavaScript membaca data piksel dan menyusun kembali nilai RGB menjadi array byte untuk didekode sebagai HTML
- Struktur ini tidak membuat situs web bisa berjalan mandiri hanya dengan favicon; tetap dibutuhkan bootstrap JavaScript terpisah, sehingga ini lebih merupakan eksperimen batas daripada sesuatu yang praktis
Cara memperlakukan favicon seperti penyimpanan
- favicon adalah ikon kecil yang ditampilkan di tab browser, tetapi pada dasarnya merupakan berkas gambar yang tersusun dari piksel dan byte
- Titik awal eksperimen ini adalah steganografi, tetapi pada demo fokusnya bukan membuatnya tampak seperti ikon, melainkan menggunakannya sebagai ruang penyimpanan murni
- Yang disimpan adalah payload HTML kecil
Website in a Favicon
Everything you're reading right now was decoded from favicon pixels.
- Prosedur encoding-nya sederhana
- Menggunakan
TextEncoder untuk mengubah HTML menjadi byte UTF-8
- Menambahkan header 4 byte yang berisi panjang payload di bagian depan
- Karena mungkin ada piksel yang tersisa, header panjang dipakai untuk menandai akhir payload yang sebenarnya
- Byte pertama disimpan di kanal merah piksel pertama, byte kedua di hijau, dan byte ketiga di biru
- Piksel berikutnya diisi dengan urutan yang sama sehingga seluruh dokumen HTML masuk ke dalam nilai warna
- Gambar hasilnya secara visual tampak seperti noise
Ukuran dan proses pemulihan
- Ukuran akhir demo sangat kecil
- Payload: 208 bytes
- Total termasuk header: 212 bytes
- Piksel yang dibutuhkan: 71 pixels
- Ukuran gambar: 9×9 pixels
- Kapasitas: 239 bytes
- Tingkat pemakaian: 87% {p:87}
- Pemulihan dilakukan hanya dengan fitur browser
- favicon dimuat sebagai gambar
- gambar digambar ke canvas
- semua piksel dibaca dengan Canvas API
- nilai RGB disusun ulang menjadi array byte
- panjang payload dibaca dari 4 byte pertama
- payload diekstrak lalu didekode menjadi teks UTF-8
- Di situs demo, saat tombol
"Render Website" ditekan, favicon dibaca dan HTML dipulihkan lalu isi halaman diganti
Batasan dan alternatif
- Kendala terbesar adalah favicon tidak bisa menjalankan seluruh situs web sendirian
- favicon berisi konten situs web
- loader JavaScript kecil untuk decoding tetap dibutuhkan secara terpisah
- Tanpa JavaScript, favicon hanyalah PNG yang memuat konten situs web
- Kegunaan praktisnya rendah
- data yang bisa disimpan sangat sedikit
- halaman harus di-bootstrap dengan JavaScript
- ada banyak cara yang lebih baik untuk mendistribusikan dokumen HTML kecil
- Alternatifnya antara lain memasukkan markup langsung ke SVG favicon, menggunakan comment chunk
tEXt, zTXt, iTXt pada PNG, atau memakai format berkas ico yang dapat memuat ikon multi-resolusi
- Situs demo: https://www.timwehrle.de/labs/favicon-site/
- Kode implementasi: https://github.com/timwehrle/favicon
1 komentar
Komentar Hacker News
Rasanya kita bisa saja tidak lewat piksel dan memakai SVG favicon, lalu menyimpan markup langsung di dalamnya dan mengekstraknya
Cukup taruh isi seperti
hello HN!difavicon.svg, pakai itu sebagai SVG favicon, lalu ekstrak dan tempelkan ke isi dokumenAtau sajikan file SVG apa adanya dan sertakan HTML sebagai embed. Secara teori seharusnya bisa didefinisikan lalu dipakai, tapi sayangnya di praktiknya baik Firefox maupun Chromium tampaknya tidak menanganinya dengan benar di dalam favicon
[\s\S]bisa ditulis lebih singkat dan lebih akurat sebagai[^]Jadi eksperimennya bisa ditumpuk satu lapis lagi: favicon-nya SVG, di dalamnya ada raster yang dienkode, dan di dalam byte itu ada HTML yang dienkode. Minimal ini terasa seperti level CTF yang bikin pusing
Tentu ini bukan ide baru. Misalnya, pada tahun 2000 seseorang menyimpan deCSS di favicon
https://web.archive.org/web/20010408040524if_/http://decss.z...
Ekstraksinya bisa dilakukan dengan
dd bs=1 skip=2238 < favicon.icoBukan berarti “tetap dibutuhkan bootstrap loader kecil untuk mendekode gambar”. Dengan HTML/PNG polyglot, semuanya bisa ditangani dalam satu file, dan sekarang kompresinya bahkan bisa lebih baik dengan format baru seperti WebP
https://web.archive.org/web/20120801001616/http://daeken.com...
Jika pengguna diarahkan ulang ke beberapa domain, cache favicon juga bisa dipakai sebagai penyimpanan. Ini pernah diusulkan sebagai potensi risiko fingerprinting[0], dan jika browser secara naif memakai ulang cache bahkan dalam mode penyamaran, ini bisa disalahgunakan untuk melacak pengguna antar profil browser
[0]: https://www.schneier.com/blog/archives/2021/02/browser-track...
Sayangnya tautan ke situs supercookie itu sudah mati
PNG punya chunk komentar tEXt, zTXt, iTXt. Kita bisa menyelipkan sebanyak apa pun isi yang diinginkan ke dalam file gambar yang tampak sepenuhnya normal. Tentu saja, unsur serunya mungkin jadi agak berkurang
Apakah waktunya cuma kebetulan? Baru satu jam lalu, tepatnya 30 menit sebelum posting ini, saya mengunggah situs yang menyimpan portofolio saham ke URL + favicon yang saya buat
https://news.ycombinator.com/item?id=48606396
“Pong in S Favicon”
https://news.ycombinator.com/item?id=48608681
Ini benar-benar cocok dengan cara berpikir seperti ini: monitor juga penyimpanan, keyboard juga penyimpanan, dan posting forum juga penyimpanan
Jika seiring waktu penyuntingan diberi variasi yang mungkin disetujui Markov, kapasitas penyimpanannya bisa lumayan besar. Selain itu, komentar kadang juga menarik secara sosial, jadi ini menjadi penyimpanan dengan fungsi ganda.
Tidak ada yang tahu apakah resep chicken casserole seseorang sebenarnya adalah handle dari GUID yang disusun dengan rumit, dan secara bercanda menunjuk ke seribu posting forum yang berbeda. Aku penasaran apakah penulisnya tahu PoC||GTFO, karena ini jelas teknik yang terasa seperti ditemukan jauh di dalam kitab suci milik Alchemist Owls
Gaya tulisannya yang terpotong-potong secara agresif dan jelas terlihat seperti hasil LLM membuatnya sangat sulit dibaca
Buat saya, penulisnya cuma terlihat ingin langsung ke intinya. Sepertinya dia tahu kalau tulisannya terlalu banyak, orang akan mulai sekadar memindai cepat
it’s/itstertukar,But.dijadikan kalimat satu kata, HTML tidak ditulis dengan huruf besar, dan ada “okayy” di dalam tanda kurung. Bukan bermaksud mengkritik penulisnya; justru saya lebih menikmati tulisan blog seperti ini karena terlihat tersusun dari ketidaksempurnaan kecil semacam ituIni mengingatkan saya pada real pixel coding milik Inigo: https://www.youtube.com/watch?v=FvS_DG8yIqQ
Sebuah intro 256-byte yang dibuat dengan menata piksel di Photoshop lalu menyimpannya sebagai exe
Fakta menarik: SVG inline apa pun bisa dipakai sebagai favicon dan dibiarkan apa adanya di dalam dokumen HTML
Dengan begini, emoji pun bisa langsung dipakai sebagai favicon. Di HN, emoji tidak ditampilkan
#rrggbbatau tautanurl(#id), maka#harus di-escape menjadi%23. Kalau tidak, itu akan diparse sebagai fragmen URL dan kode SVG akan terpotong di titik itu