55

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!

cnst
  • 2,615

9 Answers9

30

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.
Bob
  • 63,170
25

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

cnst
  • 2,615
19

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'
Anto Jose
  • 191
  • 1
  • 4
12

The accepted answer no longer works on version 106 of Firefox.

Scratchpad is replaced by Browser Console, and OS.File has been replaced with IOUtils (ref).

Here are updated steps:

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

  • Open Browser Console:

    • On Windows/Nix: Ctrl+Shift+J
    • Or through the toolbar: ToolsBrowser ToolsBrowser Console
  • In the console, click the icon in the bottom-right corner or press Ctrl+B to enter multi-line mode.

  • Use code like this in the console:

let file = '/Users/…/sessionstore-backups/recovery.jsonlz4';
let data = await IOUtils.readJSON(file, { decompress: true });
IOUtils.writeJSON(file + '.uncompressed', data);
// alternately for pretty printing
IOUtils.writeUTF8(file + '.uncompressed.pretty', JSON.stringify(data, null, 1));
  • Click the Run button or press Ctrl+Enter.

Now you can view the file in your editor of choice, or run fgrep :textarea /Users/…/sessionstore-backups/recovery.jsonlz4.uncompressed.pretty from your terminal emulator.

Wyrme
  • 121
7

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.

4

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
cnst
  • 2,615
3

The Python script from @Bob's answer is broken with latest python3 lz4 lib, but it can be fixed if you replace

import lz4

with

import lz4.block as lz4
Ph3n0x
  • 311
0

This website can convert the file to readable JSON.

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

No data is sent to the server, it's all done client-side.

0

From within Firefox 123, the solution of @wyrme doesn't work any more. I got it following way:

  1. Set the devtools.chrome.enabled preference to true in about:config (source)

  2. Open Parent Browser Console (Ctrl-Shift-J)

  3. Execute following code:

    let file = '/home/…/sessionstore-backups/recovery.baklz4'
    let fileu = file+'.uncompressed'
    let utf8 = await IOUtils.readUTF8(file, { decompress: true });
    let x = await IOUtils.writeUTF8(fileu, utf8);
    

    This should return the number of decompressed bytes

  4. Set back devtools.chrome.enabled

Extra hint: If it's about session restore, it is probably better to make this from a clean profile, so start firefox --ProfileManager.

u_Ltd.
  • 273