How to decode/decipher Mozilla Firefox proprietary .jsonlz4 format? (sessionstore-backups/recovery.jsonlz4)

There's few Google results that actually result in doable solutions, but, as per https://www.reddit.com/r/firefox/comments/2ps6wg/jsonlz4_bookmark_backups/, the following appears to work most reliably:

  • in about:config, toggle the devtools.chrome.enabled setting from the default of false to a value of true

  • open Scratchpad from within Firefox:

    • either with fn+Shift+F4 on a MacBook,
    • or Shift+F4,
    • or through the menu bar through ToolsWeb DeveloperScratchpad
  • in the menu bar within Scratchpad of Firefox, change Environment from Content to Browser (omitting this step would subsequently result in errors like Exception: ReferenceError: OS is not defined at the next step)

  • use code like the following within the Scratchpad of Firefox:

    var file = "/Users/…/sessionstore-backups/recovery.baklz4";
    //OS.File.read(file, { compression: "lz4" }).then(bytes => 
    //  OS.File.writeAtomic(file + ".uncompressed", bytes));
    
    OS.File.read(file, { compression: "lz4" }).then(bytes => {
      OS.File.writeAtomic(file + ".uncompressed.stringify",
        JSON.stringify(JSON.parse(new TextDecoder().decode(bytes)),null,1))
    });
    

    The final parameter to JSON.stringify handles how many spaces would be used at each line; putting 0 causes the whole thing to be printed on a single line, putting 1 splits the lines properly (putting 2 would create too much useless whitespace and increases the size of the file for little benefit)

  • click the Run button

  • run fgrep :textarea /Users/…/sessionstore-backups/recovery.baklz4.uncompressed.stringify from within the Terminal app


Unfortunately, due to a non-standard header, standard tools won't work. There's an open proposal to change that. Apparently the Mozilla header was devised before a standard lz4 frame format existed; it does wrap a standard lz4 block.

That said, the same bug report includes a few alternative methods. I'll list them briefly:

  • Use the dejsonlz4 tool, which includes binary builds for Windows and should be easy to build on *nix
    • lz4json is a similar tool, but relies on an external liblz4 and is somewhat easier to build on *nix but harder on Windows (outside WSL)
  • Use this fairly simple Python script: https://gist.github.com/Tblue/62ff47bef7f894e92ed5 (requires the lz4 package via pip or your package manager) -- the script appears to be python3 but is trivially adaptable to python2
  • There is a webextension available that should be able to open these. NB: while source is available, I have not verified it, and the permissions it requests are a bit concerning (especially the response to concerns)
  • In theory, you should be able to strip the first 8 bytes (e.g. with dd if=original.jsonlz4 of=stripped.lz4 bs=8 skip=1) and that should leave you with a valid lz4 block. Note that this is distinct from a lz4 frame. While most programming languages have libraries that can easily decode a block, finding a prebuilt tool to do so is more difficult, e.g. the liblz4-tool package only accepts the frame format.

I was able to extract the URLs from the {profile-dir}/sessionstore-backups/recovery.jsonlz4 file using the following free online tool designed expressly for this purpose:

https://www.jeffersonscher.com/ffu/scrounger.html

The same site offers a similar tool for decrypting jsonlz4 files from the {profile-dir}/bookmarkbackups directory.