Writing a PNG encoder in JavaScript

Dark web operatives needed to take full-page screenshots, but the Tor browser wouldn't cooperate... sometimes you need to get down to the byte-level and do it yourself.


I wrote my own PNG encoder/decoder to get around limitations of the Tor browser.

Most solutions for browser add-ons that provide full-page screenshots use the Canvas API to stitch together the screen capture images provided by the browser. This solution is fine, but the the Canvas API allows for browser fingerprinting, so for security the Tor browser disables it.

Our junior developer started working on a browser plugin to enable operatives to quickly upload screenshots to our servers from reseach machines. She started by copying screenshot code from an open-source Chrome add-on. Everything looked great until she tested with the Tor browser and found out that the screenshot code didn’t work. After discussing the inability to use the Canvas API, I suggested to our team that we could just decode the images ourselves and stitch together the pixel arrays.

I thought this was a straightforward enough suggestion, but no one wanted to do it. No worries. I don’t mind reading specifications and processing bytes. It was a lot of fun for me and turned into valuable tool for our team.


I'm working on a long-form article describing this project, complete with code samples, code review and screenshots. If you'd like to access an early draft of the content, enter your email below and I will get in touch.