# firefox_decrypt reads a local profile's saved passwords, and only when you know the master password

> A single-file Python utility that loads Mozilla's NSS library and prints the saved passwords from a profile on your own machine. It states plainly that it does not crack or brute-force the master password. Two different NSS version floors appear in the repository, and the pinned dev environment covers one platform out of three.

**unode/firefox_decrypt** — Firefox Decrypt is a tool to extract passwords from Mozilla (Firefox™, Waterfox™, Thunderbird®, SeaMonkey®) profiles

- Repository: https://github.com/unode/firefox_decrypt
- Stars: 2,486 · Forks: 345
- Language: Python
- License: GPL-3.0
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/unode-firefox-decrypt

## Two different NSS version floors, 3.113 in the text and 3.118 in the environment

Firefox 144 introduced a new encryption algorithm for the password store and, in the same change, broke direct use of the bundled libnss3 shared object. The note about that says that on Linux you need libnss3 version 3.113 or newer to read a Firefox 144 or later profile, and points at issue 120. The pinned environment states a different floor. The project file declares nss from conda-forge with a version range of 3.118 up to but not including 4. So a machine on 3.113 through 3.117 satisfies the number written in the documentation and fails the constraint the environment enforces. Both numbers are current in the repository and neither points at the other, so a version that works by the prose may not resolve in the pinned environment.

## The pinned environment covers linux-64 while three platforms are documented

The pixi configuration in the project file names one channel, conda-forge, and one platform, linux-64. That is the entire reproducible environment. The documentation, by contrast, describes three operating systems through the library paths alone: libnss3.so in a directory on Linux, libnss3.dylib on Mac, and nss3.dll on Windows, each with its own command form. The table of contents also carries a Windows troubleshooting heading alongside a MacOSX one. So there are three platforms with per-platform instructions and one platform with a locked dependency set. There is also no runtime dependency list in the project file at all, which fits a tool that locates and loads the NSS library at runtime rather than installing a binding for it. The resolution itself is committed: a pixi.lock sits at the repository root, so the single platform's package set is reproducible even though the other two platforms have no equivalent.

## The NSS library is located by heuristics that can load the wrong build

Decoding requires libnss3, which the documentation says ships with most Mozilla products. The tool searches for a compatible library using a series of heuristics, and it is explicit about the failure mode: it is usually able to find a compatible library but may in some cases load an incorrect or incompatible version, and the request in that case is to file a bug report. Since version 1.1.1 you can bypass the search with the NSS_LIB_PATH environment variable, which is prioritised and, if no compatible library is found there, falls back to the built-in heuristics rather than failing:

```
# On Linux it will look for libnss3.so in /opt/nss/lib/
# On Mac it will look for libnss3.dylib
NSS_LIB_PATH=/opt/nss/lib/ python firefox_decrypt.py

# On Windows it will look for nss3.dll
set NSS_LIB_PATH=D:\NSS\lib\ && python firefox_decrypt.py
```

You can confirm which file was actually used by running with -vv and looking for the loaded line:

```
(...) DEBUG - Loading NSS library from /opt/nss/lib/libnss3.so
(...) DEBUG - Loaded NSS library from /opt/nss/lib/libnss3.so
```

## The pass format writes into a password store, and the project warns about it

Five output formats are offered. human displays one record for every three lines, csv is spreadsheet-like with separate flags for the delimiter and the quote character, tabular is the same but tab-delimited, and json is the machine-readable one. The fifth is different in kind: pass does not format text for you to redirect, it calls the passwordstore.org command directly to export the passwords. The documentation attaches a warning to that option in its own words, saying it can produce unintended consequences and that you should back up your password store before using it. That is the only format with an external side effect, and it is the one the project singles out. The other four write to standard output, which is why the documentation suggests piping through grep with two lines of context to pick out one record.

## Non-interactive mode reads the master password from stdin and numbers profiles from one

Normally the tool prints a numbered list of profiles and waits for you to type a number, then prompts for the master password. A non-interactive mode enabled with -n or --no-interactive bypasses both prompts. With more than one profile present you must also pass the selection with -c or --choice, and the number starts at 1, so a choice of 0 is not a valid way to say the first profile. Profiles can be listed on their own with -l or --list, which prints one numbered line per profile and nothing else. The master password is read from standard input rather than from a prompt, which means it arrives through a pipe: the documentation's own examples assign it to a shell variable and echo it into the command, then unset the variable afterwards, and it also shows the short combined form with the two flags run together. The listing in those examples carries the profile directory names Firefox generates, including suffixed ones, so a profile that exists is not necessarily the default one. An unusual profile location is handled by passing the folder that contains profiles.ini rather than the file itself.

## The version is a build placeholder and the documentation points at a release page

The project file gives the version as 1.1.3+git, which is the placeholder setuptools-scm substitutes from repository tags at build time, and the build requirements pair setuptools with setuptools-scm for that purpose. The documentation refers to specific versions in passing: 1.0.0 as the point where Python 3.9 became required, 1.1.1 as the point where NSS_LIB_PATH was added, and 0.7.0 as the recommended release for anyone who still needs Python 2. It also sends readers to the project's releases page and to a URL for the 0.7.0 tag. The repository's release list is empty, so the tag referenced by name is the only place that version is pinned, and a user arriving at the releases page has nothing to read. There is no CHANGELOG pointer in the usage sections to stand in for it.

## One script at the root, a console entry point, and no declared dependencies

The whole program is a single Python file at the repository root, firefox_decrypt.py, run directly with python firefox_decrypt.py or through pixi with pixi run python firefox_decrypt.py. A console script is also declared, mapping the name firefox-decrypt to a run_ffdecrypt entry point, so an installed copy can be invoked by name rather than by path. The project file declares no runtime dependencies whatsoever, which is consistent with the library being discovered and loaded at runtime instead of being installed as a package. A tests directory and a pixi.lock sit alongside the script. The two supported edges of the version range are stated with different confidence: Python 3.9 or newer from 1.0.0 with Python 2 dropped, and Firefox 3 or older explicitly not officially supported, where the offered remedy is a patch living in an open pull request rather than a merged change.

## Conclusion

Use this to recover a saved password from a profile on a machine you control, where you know the master password or where none was set. It is not a password cracking tool and it will not get you a master password you have forgotten. Three things to check first. The library it loads is found by search heuristics that the project admits can pick an incompatible build, so check the high-verbosity output before trusting an empty result. The library version floor differs between the documentation and the pinned environment. And the pass output format writes into a password store, which is the one option the project itself attaches a warning to.

## FAQ

### What does Firefox Decrypt need in order to read a profile?

Access to libnss3, which ships with most Mozilla products, and the master password when the profile has one. It states that it does not attempt to crack or brute-force the master password and simply fails to recover data if the password is unknown.

### Which output formats does Firefox Decrypt support?

human, csv, tabular, json and pass. The csv format takes extra flags for the delimiter and quote character. The pass format calls the passwordstore.org command directly rather than printing text, and the documentation warns to back up a password store first.

### Can Firefox Decrypt run without prompts?

Yes. A non-interactive flag bypasses the profile and master password prompts. When several profiles exist you must also give the choice number, counted from 1, and the master password is read from standard input.

### Does Firefox Decrypt work with Thunderbird and SeaMonkey profiles?

Its stated scope covers Mozilla Firefox, Waterfox, Thunderbird, SeaMonkey and derivatives. Profiles are discovered from a profiles.ini, and the folder containing that file can be passed as an argument when the location is unusual.

### What happens if the tool loads the wrong NSS library?

It may load an incorrect or incompatible version, which the documentation describes as a known failure mode of the search heuristics and asks to be reported. Setting NSS_LIB_PATH bypasses the search, and running with -vv prints the library file actually loaded so you can confirm it.

## Sources

- [Issues](https://github.com/unode/firefox_decrypt/issues)
- [License: GPL-3.0](https://github.com/unode/firefox_decrypt/blob/main/LICENSE)
- [README](https://github.com/unode/firefox_decrypt/blob/main/README.md)
- [unode/firefox_decrypt on GitHub](https://github.com/unode/firefox_decrypt)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/unode-firefox-decrypt
