I Stored a Website in a Favicon

310 points116 comments2 days ago
Tepix

Instead of going via pixels, why not use a SVG favicon and directly store markup inside it and extract it?

Use this favicon.svg:

    <svg xmlns="http://www.w3.org/2000/svg">
    <circle cx="50%" cy="50%" r="50%" fill="orange"/>
    <p>hello HN!</p>
    </svg>
use this in your <head> to use a svg favicon:

    <link id="favicon" rel="icon" href="favicon.svg" type="image/svg+xml">
finally, use this in your <body> to extract it and add it to your document body:

    <script>
    fetch(favicon.href).then(r => r.text()).then(t => document.body.innerHTML += t.match(/<p[\s\S]*p>/)[0]);
    </script>
show comments
Retr0id

> You still need a tiny bootstrap loader to decode the image.

Nope, you can do it all in a single file with an html/png polyglot (and nowadays you can get better compression ratios with newer formats like webp).

https://web.archive.org/web/20120801001616/http://daeken.com...

show comments
sheept

You can use the favicon cache as storage too, by redirecting users across domains. It's been proposed as a potential fingerprinting risk[0], and if a browser naively reuses the cache for incognito mode, it could be used to track users across browser profiles.

[0]: https://www.schneier.com/blog/archives/2021/02/browser-track...

show comments
Walf

PNG has comment chunks tEXt, zTXt, and iTXt. You can have a completely normal image whose file is stuffed with as much content as you want. That is less fun, I suppose.

show comments
franciscop

Is this timing coincidence? I just submitted 1h (30 mins before this) ago a website I just made about storing your stock porfolio in a URL + favicon!

https://news.ycombinator.com/item?id=48606396

show comments
esquivalience

I found the agressively staccato, clearly LLM-generated content extremely difficult to read.

show comments
MomsAVoxell

Oh, I am so aligned with this mentality:

    A monitor is storage.

    A keyboard is storage.
Forum posts are storage. Markov-approved tweaks in an edit, over time, certainly enough for quite a lot of storage. Dual-use storage to boot, since .. you know .. sometimes the comments are socially interesting.

Best thing is, nobody really knows if their chicken casserole recipe isn't just a handle to a carefully constructed GUID pointing across to .. lets say, for humor .. a thousand different forum postings ...

I do have to wonder if the author is familiar with PoC||GTFO, for this is certainly a technique one will find deep within the depths of the Alchemist Owls' holy tomes...

show comments
clusmore

I'd love to see you try serving the exact same file for both but the trick is that you need to return different Content-Type headers depending on what is requested. When the browser requests /favicon from a navigation event it will use Accept: text/html etc, you return the file with Content-Type: text/html and inside the response you have a <link rel="favicon" href="/favicon" type="img/png"> literally the same resource but the browser will now likely fetch with Accept: image/... and you could return the same file with Content-Type: image/png and the same resource will get used for both. Unless the browser caches the response, I feel like this would work.

If you don't control the headers of your webserver (eg GitHub Pages) I would settle for a symlink favicon.png that just links back to favicon.html which I think would trick the server into returning different Content-Types.

jorisw

Fun Fact: You can use any inline SVG for a favicon and keep it right in the HTML document.

This also allows you to use an emoji directly as a favicon, like so:

  <link
    rel="icon"
    type="image/svg+xml"
    href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>(your emoji here)</text></svg>"
  />
(HN isn't showing the emoji)
show comments
econ

I played with this once hoping the browser wouldn't care what the file was.

The plan came from an experiment from long ago where I put 1x1 images at the end on my pages, the images loaded from websites my page linked to. Preloading the assets made those pages load much faster. Sadly it also broke pages that served "hot linking images not allowed" text on images.

The new plan was to have a javascript or css file called favicon.ico so that the browser would load it at the same time the html was requested. Then one wouldn't have to wait for the html to be parsed for the second round trip to happen.

Sadly it didn't work.

cfrs

That reminded me of Inigo's "real pixel coding" https://www.youtube.com/watch?v=FvS_DG8yIqQ

A 256b intro coded by placing pixels in photoshop and saving into an exe.

inglor

Cool! Here is a GH repo demonstrating unbounded favicons I made 11 years ago - it crashes some browsers - wanna guess how long it took each one to fix it :D https://github.com/benjamingr/favicon-bug

1vuio0pswjnm7

Not a new idea of course. For example, back in 2000, someone stored deCSS in a favicon

https://web.archive.org/web/20010408040524if_/http://decss.z...

To extract

   dd bs=1 skip=2238 < favicon.ico
jcubic

Does't work for me. It rendered some garbage:

:f3=Ygbukte!in"c"Hbviann:1h3> =n= " Exgtyvhkle znt%pfsdafipg thfivlmu "vas dcdpeed hrondbvjbno"rixfls, ;.q>

I use Helium on Linux with Polish locale.

tetrisgm

Love it. Did you see the old effort to store the page in the url? https://github.com/jstrieb/urlpages

show comments
berkes

I'd imagine the (aggressive) caching of the favicon by browsers makes it a challenge, but you could generate the favicon dynamically, then have JS extract the sequentially. Basically streaming arbitraily large content to a webpage via favicons. Via blocks of 239 bytes.

It may be a fun, novel way to proxy webpages that are otherwise blocked. Though, i guess, the service rendering the favicons can just as easily be blocked then.

echoangle

> The length header is important because the image itself may contain unused pixels at the end. If there's no length value, there's no way to know where the real payload stops.

Not really, can’t you just pad with 0 bytes and stop reading when you encounter one that’s not part of the current Unicode codepoint?

show comments
herodoturtle

How long before someone ports DOOM into a favicon? ^_^

(For the technical gurus here, would that even be possible?)

show comments
Gabrys1

Have an index.html that's also (byte-to-byte equal) served as favicon.ico. If that page "works" and the favicon doesn't show garbage, it is a website stored in a favicon (by my standards).

divvsaxena

This is one of those projects that's completely impractical but makes the web more interesting. I love seeing people explore weird constraints just to see what's possible.

terrycody

Any real usage scenarios for this? I mean, can it be used as anti-filter or whatever things.

scoot

Would have been more fun if the blogpost was rendered from the favicon.

titularcomment

Painful read.

Related interesting project: https://github.com/EtherDream/web2img

superjose

Pretty cool tbh!!! Would have loved seeing the decoder code!!!

It's also pretty interesting to think how an attacker could exploit images on his behalf. Never thought that would be a way!!!

Thanks!

show comments
brtkwr

Hmm this is cool but what are the practical use cases?

It didn’t load first time round on my browser (Brave) without disabling its prevent tracking feature…

show comments
beardyw

I would have used a minimal service worker to unpack the web data and present it as if it were just a normal page being loaded.

frankzero

I personally won't do things this way, but this is really cool and I could see the applications already.

soanvig

Honestly it didn't interest me, but I do remember from back in the days full websites rendered by a browser from... Empty files. https://mathiasbynens.be/notes/css-without-html

Izmaki

Wait 'til the author discovers that you can use ping (ICMP) to transfer data, too! :)

momoraul

The browser already asks for the favicon on every page. Might as well put it to work.

bozdemir

Very cool. I wonder is it possible to make a simple game with also leveraging the webassembly?

show comments
aaubry

A neat improvement would be to make the decoder into a bookmarklet. This would avoid the overhead of serving the script. Of course you would rely on the user having the bookmarklet installed, but when you serve HTML you also rely on the user having a web browser installed.

franze

also https://pong-in-a-favicon.franzai.com/ for further favicon (mis)use

show comments
ab_wahab01

Fascinating concept! Thanks for sharing this!

abc123abc123

Bravo Maestro! Wonderful performance! =)

fitsumbelay

very cool and interesting after reading just the title I wrongly assumed this would be about svg

jibal

Surprised that a minimal "website" only requires a small image = few pixels = few bytes to store it? Um, ok.

neon_me

Is it cake? Game for devs.

charcircuit

You can literally just use the file itself as the favicon. There is no need to over complicate it.

cp index.html favicon.png

deemwar

looks good

pradeep4j

[flagged]

[deleted]
swordlucky666

[dead]

pizzaballs

[dead]

creatorpilot

[flagged]

heroku

[dead]

anujshashimal98

[flagged]

shaharamir

Amazing!

fvckaigotohell

AI generated garbage. Blocked