← Back to context

Comment by Tepix

14 hours ago

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>

"why not alternative", would be better framed as, "here's a fun variation" — because both approaches are just playing around with technology, for fun / curiosity / exploration. Storing in the pixels is a fun approach, resulting in something Rube Goldberg-esque.

Hey, yeah, I wrote the article. This (of course) would be more practical. Thanks for pointing it out. I wanted the payload to "live" in actual pixel data rather than hidden text inside an XML file. That’s why I went this way :)

  • If you wanted to play around and do something a little more challenging (though you'd be bulking up the javascript) then one thing you could do is play with a bespoke html compression. You could store the tags in 4 bits `0001` first bit, tag open or close, and the remaining 3 bits indicate which tag is being used (div/p/b/h1/etc). With at least one of the values like `0111` indicating text is following and another tag like `1111` indicating that an unsupported tag follows.

    If you extend it out to 8 bits you can pretty nearly store all the html tags (it'd give you 256 tags to play with).

Regular expressions? Ugh. Encode it properly as XML in the correct namespace, load it so, and take it from that.

Or just serve the SVG file and use <foreignObject> to embed the HTML, and include <link rel="icon" href=""> inside it. In theory you should be able to define a <view id="icon"> and use <link rel="icon" href="#icon">, but in practice neither Firefox nor Chromium seems to be handling that properly in a favicon, which is disappointing.

Just because it's my windmill to tilt at: `[\s\S]` can be written shorter and more precisely as `[^]`.

  • ai says [^] is not portable; I did not test it. Too bad, I'll stick to [\s\S].

    • Too bad, indeed. It's well-defined in javascript (and thus, appropriate in this admittedly niche context). It's non-portable across different regex engines, yes.

An SVG can embed raster images: base64 encoded bytes.

So you could layer this experiment: favicon is svg, that contains encoded raster, whose bytes are encoded html.

At the very least it would make a mindboggling CTF step.