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

I'm trying to get a handle on Mozilla Firefox's proprietary file format .jsonlz4, used, for example, for sessionstore-backups/recovery.jsonlz4, but to no avail.

How do I get back my data, specifically, some long text I've typed in some textareas of a crashed session? It's my data!


Solution 1:

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

Solution 2:

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.

Solution 3:

I found the following methods to be working, testing on Ubuntu 20.04:

Method 1: Using the mozlz4 binary from GitHub:

Download the linux binary for mozlz4 from https://github.com/jusw85/mozlz4. Then run the following:

chmod u+x mozlz4-linux

./mozlz4-linux -x filename.jsonlz4

Method 2: Using the lz4json package from Ubuntu repos:

Ubuntu 20.04 repos have a package named lz4json. I haven't checked whether it is present on previous Ubuntu versions.

To install and use that, run

sudo apt install lz4 lz4json

lz4jsoncat ~/.mozilla/firefox/*default*/sessionstore-backups/recovery.jsonlz4

The above output will show a minified json. To make it readable, you can use the 'jq' json parser:

sudo apt install jq

# then pipe the output of the previous command through jq to make it readable:
lz4jsoncat ~/.mozilla/firefox/*default*/sessionstore-backups/recovery.jsonlz4 | jq

If you just want to see the list of URLs and the page titles, you can use this:

lz4jsoncat ~/.mozilla/firefox/*default*/sessionstore-backups/recovery.jsonlz4 \
  | jq '.["windows"] | .[0] | .["tabs"] | .[] | .["entries"] | .[0] | .url,.title' \
  | grep -v 'New Tab' | grep -v 'about:newtab' | sed 's/"http/\n"http/g'

Solution 4:

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.

Solution 5:

On UNIX® and UNIX-like systems, like Mac OS X with MacPorts, FreeBSD, OpenBSD or NetBSD with pkgsrc, the following https://github.com/cnst/lz4json fork of lz4json could also be used to compile cleanly out of the box, e.g., on Mac OS X w/ MacPorts:

sudo port install lz4
git clone https://github.com/cnst/lz4json.git
cd lz4json
make
./lz4jsoncat ~/Library/Application\ Support/Firefox/Profiles/CHANGE\
THIS.default/sessionstore-backups/recovery.jsonlz4 \
| python -m json.tool | fgrep :textarea | more