將網站儲存在 Favicon 中:技術概念驗證
將網站儲存在 Favicon 中:技術概念驗證
將 HTML 資料編碼至影像像素中
Tim Wehrle 展示了一個概念驗證,將網站的 HTML 內容直接儲存在 favicon 中。這是透過將影像像素的 RGB(紅、綠、藍)通道視為原始位元組儲存空間來實現的,有效地將 favicon 作為資料容器而非視覺圖示使用。
編碼過程
為了將網站儲存在 favicon 中,內容會從文字轉換為位元組並映射到像素:
- 位元組轉換:使用
TextEncoder將 HTML 載荷(payload)轉換為位元組陣列。 - 長度標頭:在陣列前加上一個四位元組的標頭以儲存載荷長度。這確保了解碼器確切知道資料在哪裡結束,因為影像可能包含末尾未使用的像素。
- 像素映射:每個位元組會被分配給一個顏色通道。第一個位元組成為第一個像素的紅通道,第二個位元組成為綠通道,第三個位元組成為藍通道。此過程會依序在影像中的所有像素上重複進行。
儲存效率與尺寸
由於每個像素儲存三個位元組的資料,因此相對於影像尺寸而言,儲存容量很高。對於一個 208 位元組加上 4 位元組標頭(總共 212 位元組)的載荷,僅需要 71 個像素。一個 9x9 像素的正方形影像提供 81 個像素,總容量為 239 位元組。在此特定實作中,212 位元組的載荷利用了 9x9 影像中 87% 的可用空間。
解碼與渲染內容
檢索被儲存的網站需要一個 JavaScript bootstrap loader 來讀取影像資料並重建 HTML。
檢索工作流程
- 影像載入:瀏覽器將 favicon 加載為標準影像。
- Canvas 渲染:影像被繪製到 HTML5 Canvas 元素上。
- 像素提取:使用 Canvas API 讀取每個像素的 RGB 值。
- 重建:從 RGB 通道中以與寫入時相同的順序提取位元組,並使用前四個位元組來確定載荷長度。
- 解碼:將位元組陣列解碼回 UTF-8 文字並注入到文件本文(document body)中。
Web 資產中的替代資料儲存方法
雖然基於像素的方法是一種邊界測試的創意練習,但其他技術方法也存在於隱藏或儲存資料於 Web 資產中:
- SVG Markup:由於 SVG favicon 是基於 XML 的,因此標記或文字可以直接儲存在 SVG 檔案中,並透過
fetch請求和 regex 匹配來提取。 - PNG Metadata:PNG 格式支援特定的註釋區塊(
tEXt、zTXt和iTXt)來允許儲存任意文字資料,而不改變影像的視覺外觀。 - ICO Format:
.ico格式在單一檔案中支援不同解析度的多個圖示,提供了額外的資料空間。 - Favicon Cache:一些研究人員指出,如果瀏覽器在無痕模式下天真地重複使用快取,favicon 快取可以用於跨網域的追蹤或指紋辨識。
技術限制
此方法並非標準 Web 託管的實際替代方案。它需要一個 JavaScript bootstrap loader 才能運作,這意味著 favicon 無法單獨渲染網站。此外,能儲存的資料量受到影像尺寸的極大限制。正如社群成員所指出的,一些注重隱私的瀏覽器(例如 Brave)可能會在啟用追蹤防止功能時阻擋 favicon 的載入,這將會阻止 bootstrap loader 存取資料。