Skip to content

Firefox 144 now uses AES-256-CBC instead of 3DES-CBC #120

Description

@jrw

As of sometime around Oct 1, 2025, Firefox now uses a different encryption algorithm, so firefox_decrypt.py no longer works.

To reproduce, just attempt to run against a version of Firefox >= 144. I get:
ERROR - Username/Password decryption failed. Credentials damaged or cert/key file mismatch.

Linux Mint 21.3 (Virginia) 64 bits
Firefox 144.0.2
Python 3.10.12
firefox_decrypt.py 1.1.1+git

Activity

  1. unode commented on Oct 30, 2025

    @unode
    Owner

    @jrw thanks for the report! I haven't tested with the latest Firefox version.

    Can you try to install NSS version 3.113 or newer? AES support was supposedly introduced in this libnss version.

    The discussion about missing AES support took place here.

  2. jrw commented on Oct 30, 2025

    @jrw
    Author

    On my system, I see 3 different versions of NSS under /usr/lib:

    /usr/lib/firefox/libnss3.so
    /usr/lib/thunderbird/libnss3.so
    /usr/lib/x86_64-linux-gnu/libnss3.so
    

    If I run LD_LIBRARY_PATH=/usr/lib/firefox firefox_decrypt.py then I am able to decrypt my firefox passwords. However, using the other two directories for LD_LIBRARY_PATH fails, as I described in the issue.

    Under /etc/ld.so.conf.d/, I have:

    /etc/ld.so.conf.d/fakeroot-x86_64-linux-gnu.conf:
    /usr/lib/x86_64-linux-gnu/libfakeroot
    
    /etc/ld.so.conf.d/i386-linux-gnu.conf:
    # Multiarch support
    /usr/local/lib/i386-linux-gnu
    /lib/i386-linux-gnu
    /usr/lib/i386-linux-gnu
    /usr/local/lib/i686-linux-gnu
    /lib/i686-linux-gnu
    /usr/lib/i686-linux-gnu
    
    /etc/ld.so.conf.d/libc.conf:
    # libc default configuration
    /usr/local/lib
    
    /etc/ld.so.conf.d/x86_64-linux-gnu.conf:
    # Multiarch support
    /usr/local/lib/x86_64-linux-gnu
    /lib/x86_64-linux-gnu
    /usr/lib/x86_64-linux-gnu
    

    So, I'm guessing that the call to ct.CDLL(nsslib) in the firefox_decrypt.py code on line 237, where the value of nsslib is "libnss3.so" looks to be using /usr/lib/x86_64-linux-gnu/libnss3.so, which apparently doesn't support choosing the encryption algorithm from the encrypted blob itself.

    In any case, I have my work-around. Thanks for getting me pointed in the right direction for that!

  3. unode commented on Oct 31, 2025

    @unode
    Owner

    Yes, it looks like you may have some libs that are compatible with the new encryption (those bundled with Firefox) and some that aren't (nss installed system-wide).
    The latter was probably being loaded first.

    I also notice from your logs that your bundled libs live in /usr/lib/firefox and /usr/lib/thunderbird.
    Currently firefox_decrypt checks only /usr/lib and not subfolders so this is something we can improve.

    Thanks for the detailed report!

  4. unode commented on Oct 31, 2025

    @unode
    Owner

    Can you check if 7d86cb2 works for you without the LD_LIBRARY_PATH override?

  5. jrw commented on Oct 31, 2025

    @jrw
    Author

    I can check, but it will have to wait for a week+ as I'm going out of town this morning.

  6. pepa65 commented on Nov 7, 2025

    @pepa65

    Can you check if 7d86cb2 works for you without the LD_LIBRARY_PATH override?

    For me this doesn't work, relevant part of the debug:

    2025-11-07 10:31:57,187 - INFO - Running firefox_decrypt version: 1.1.1+git
    2025-11-07 10:31:57,187 - DEBUG - Parsed commandline arguments: Namespace(profile='~/.mozilla/firefox', format=<class '__main__.HumanOutputFormat'>, csv_delimiter=';', csv_quotechar='"', csv_header=True, pass_username_prefix='', pass_prefix='web', pass_cmd='pass', pass_always_with_login=False, interactive=True, non_fatal_decryption=False, choice=None, list=False, encoding='utf-8', verbose=2)
    2025-11-07 10:31:57,188 - DEBUG - Running with encodings: stdin: utf-8, stdout: utf-8, stderr: utf-8, locale: UTF-8
    2025-11-07 10:31:57,188 - DEBUG - Loading NSS library from firefox/libnss3.so
    2025-11-07 10:31:57,188 - DEBUG - Loading NSS library from thunderbird/libnss3.so
    2025-11-07 10:31:57,188 - DEBUG - Loading NSS library from libnss3.so
    2025-11-07 10:31:57,188 - DEBUG - Loaded NSS library from libnss3.so
    

    It seems to still prefer to use the OS's NSS library over the firefox one (which is the only one that works).

    • Linux Mint 22.2
    • python 3.12.3-0ubuntu2
    • firefox 144.0.2+linuxmint1+zara
    • NSS_3.79 listed as latest for /usr/lib/x86_64-linux-gnu/libnss3.so (while /usr/lib/firefox/libnss3.so has NSS_3.116)
  7. jrw commented on Nov 10, 2025

    @jrw
    Author

    It doesn't work for me either (the LD_LIBRARY_PATH workaround still works however):

    $ ./firefox_decrypt.py -vv
    2025-11-10 01:42:54,454 - INFO - Running firefox_decrypt version: 1.1.1-6-g7d86cb2
    2025-11-10 01:42:54,454 - DEBUG - Parsed commandline arguments: Namespace(profile='~/.mozilla/firefox', format=<class '__main__.HumanOutputFormat'>, csv_delimiter=';', csv_quotechar='"', csv_header=True, pass_username_prefix='', pass_prefix='web', pass_cmd='pass', pass_always_with_login=False, interactive=True, non_fatal_decryption=False, choice=None, list=False, encoding='utf-8', verbose=2)
    2025-11-10 01:42:54,454 - DEBUG - Running with encodings: stdin: utf-8, stdout: utf-8, stderr: utf-8, locale: UTF-8
    2025-11-10 01:42:54,454 - DEBUG - Loading NSS library from firefox/libnss3.so
    2025-11-10 01:42:54,454 - DEBUG - Loading NSS library from thunderbird/libnss3.so
    2025-11-10 01:42:54,454 - DEBUG - Loading NSS library from libnss3.so
    2025-11-10 01:42:54,455 - DEBUG - Loaded NSS library from libnss3.so
    2025-11-10 01:42:54,455 - DEBUG - Reading profiles from /home/..../.mozilla/firefox/profiles.ini
    2025-11-10 01:42:54,455 - DEBUG - Read profiles ['Profile0', 'Install4F96D1932A9F858E', 'Install6230AD9FB497EC11', 'General']
    2025-11-10 01:42:54,455 - DEBUG - Initializing NSS with profile 'sql:/home/..../.mozilla/firefox/.....default-release'
    2025-11-10 01:42:54,457 - DEBUG - Initializing NSS returned 0
    2025-11-10 01:42:54,457 - DEBUG - Retrieving internal key slot
    2025-11-10 01:42:54,457 - DEBUG - Internal key slot <__main__.LP_PK11SlotInfo object at 0x7f9c53f56bc0>
    
    Primary Password for profile /home/..../.mozilla/firefox/.....default-release:
    2025-11-10 01:42:58,380 - DEBUG - Authenticating with password '....'
    2025-11-10 01:42:58,398 - DEBUG - Checking user password returned 0
    2025-11-10 01:42:58,398 - DEBUG - Database location: /home/..../.mozilla/firefox/.....default-release/logins.json
    2025-11-10 01:42:58,398 - INFO - Using /home/..../.mozilla/firefox/.....default-release/logins.json for credentials.
    2025-11-10 01:42:58,398 - INFO - Decrypting credentials
    2025-11-10 01:42:58,398 - DEBUG - Reading password database in JSON format
    2025-11-10 01:42:58,399 - DEBUG - Decrypting username data '....'
    2025-11-10 01:42:58,426 - DEBUG - Decryption of data returned -1
    2025-11-10 01:42:58,426 - ERROR - Username/Password decryption failed. Credentials damaged or cert/key file mismatch.
    2025-11-10 01:42:58,426 - DEBUG - SEC_ERROR_INVALID_KEY: The key does not support the requested operation.
    
  8. unode commented on Nov 10, 2025

    @unode
    Owner
    (...)
    2025-11-10 01:42:54,455 - DEBUG - Loaded NSS library from libnss3.so
    (...)
    

    This indicates that it is using the libnss3.so installed system-wide (likely /usr/lib/ or /usr/lib64) and that version is too old and doesn't support the new algorithm.

    Where are you pointing your LD_LIBRARY_PATH to?

  9. unode commented on Nov 10, 2025

    @unode
    Owner

    I think I see where the issue might be coming from. One extra setting was still giving priority to the system-wide lib.

    Can you both check if the changes introduced in 9114470 fix it for you?

  10. unode commented on Nov 10, 2025

    @unode
    Owner

    The lib finding machinery is now very error-prone. We'll need to make the process smarter by reading both the DB and the lib information and rejecting the combination if the two aren't compatible.

    Hopefully the last workaround gives us some more time but it looks like a partial rewrite is in the horizon.
    If any of you would be interested in contributing, I would appreciate the help as I don't see myself finding the time anytime soon.

  11. jrw commented on Nov 10, 2025

    @jrw
    Author

    It looks like its still not finding it without LD_LIBRARY_PREFIX:

    2025-11-10 14:43:47,795 - INFO - Running firefox_decrypt version: 1.1.1-9-g9114470
    2025-11-10 14:43:47,795 - DEBUG - Parsed commandline arguments: Namespace(profile='~/.mozilla/firefox', format=<class '__main__.HumanOutputFormat'>, csv_delimiter=';', csv_quotechar='"', csv_header=True, pass_username_prefix='', pass_prefix='web', pass_cmd='pass', pass_always_with_login=False, interactive=True, non_fatal_decryption=False, choice=None, list=False, encoding='utf-8', verbose=2)
    2025-11-10 14:43:47,795 - DEBUG - Running with encodings: stdin: utf-8, stdout: utf-8, stderr: utf-8, locale: UTF-8
    2025-11-10 14:43:47,795 - DEBUG - Loading NSS library from ./firefox/libnss3.so
    2025-11-10 14:43:47,796 - DEBUG - Loading NSS library from ./thunderbird/libnss3.so
    2025-11-10 14:43:47,796 - DEBUG - Loading NSS library from ./libnss3.so
    2025-11-10 14:43:47,796 - DEBUG - Loading NSS library from /usr/lib64/firefox/libnss3.so
    2025-11-10 14:43:47,796 - DEBUG - Loading NSS library from /usr/lib64/thunderbird/libnss3.so
    2025-11-10 14:43:47,796 - DEBUG - Loading NSS library from /usr/lib64/libnss3.so
    2025-11-10 14:43:47,796 - DEBUG - Loading NSS library from /usr/lib64/nss/firefox/libnss3.so
    2025-11-10 14:43:47,796 - DEBUG - Loading NSS library from /usr/lib64/nss/thunderbird/libnss3.so
    2025-11-10 14:43:47,796 - DEBUG - Loading NSS library from /usr/lib64/nss/libnss3.so
    2025-11-10 14:43:47,796 - DEBUG - Loading NSS library from /usr/lib/firefox/libnss3.so
    2025-11-10 14:43:47,796 - DEBUG - Loading NSS library from /usr/lib/thunderbird/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /usr/lib/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /usr/lib/nss/firefox/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /usr/lib/nss/thunderbird/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /usr/lib/nss/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /usr/local/lib/firefox/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /usr/local/lib/thunderbird/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /usr/local/lib/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /usr/local/lib/nss/firefox/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /usr/local/lib/nss/thunderbird/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /usr/local/lib/nss/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /opt/local/lib/firefox/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /opt/local/lib/thunderbird/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /opt/local/lib/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /opt/local/lib/nss/firefox/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /opt/local/lib/nss/thunderbird/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /opt/local/lib/nss/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /home/..../.nix-profile/lib/firefox/libnss3.so
    2025-11-10 14:43:47,797 - DEBUG - Loading NSS library from /home/..../.nix-profile/lib/thunderbird/libnss3.so
    2025-11-10 14:43:47,798 - DEBUG - Loading NSS library from /home/..../.nix-profile/lib/libnss3.so
    2025-11-10 14:43:47,798 - DEBUG - Loading NSS library from firefox/libnss3.so
    2025-11-10 14:43:47,798 - DEBUG - Loading NSS library from thunderbird/libnss3.so
    2025-11-10 14:43:47,798 - DEBUG - Loading NSS library from libnss3.so
    2025-11-10 14:43:47,798 - DEBUG - Loaded NSS library from libnss3.so
    
  12. jrw commented on Nov 10, 2025

    @jrw
    Author

    Your code doesn't show the exception that's coming back when it tries to load /usr/lib/firefox/libnss3.so, but I added a line of code to show it: /lib/x86_64-linux-gnu/libnssutil3.so: version `NSSUTIL_3.101' not found (required by /usr/lib/firefox/libnss3.so)
    So, nss: ct.CDLL = ct.CDLL(nsslib) is getting that exception when nsslib is /usr/lib/firefox/libnss3.so, but somehow later on when loading libnss3.so from the systemwide library path (augmented by LD_LIBRARY_PATH) it is able to succeed without an exception.

  13. pepa65 commented on Nov 10, 2025

    @pepa65

    Why can't you just always use the Firefox nsslib? That is the one that encrypted them in the first place. It would be nice if there is an option to always use LD_LIBRARY_PATH=/usr/lib/firefox by specifying it in the code so users don't have to prefix the command with it.

  14. jrw commented on Nov 11, 2025

    @jrw
    Author

    Unfortunately, LD_LIBRARY_PATH is non-operative (except for child processes) if it is set in the code, unless the code re-execs itself. LD_LIBRARY_PATH must be set properly before the python interpreter is run. But I do agree that it would be best to use the library that firefox is using if that can be determined.

  15. unode commented on Nov 11, 2025

    @unode
    Owner

    /lib/x86_64-linux-gnu/libnssutil3.so: version `NSSUTIL_3.101' not found (required by /usr/lib/firefox/libnss3.so)

    This is a similar problem to #98 . Chained dependencies.

    @jrw is correct in that LD_LIBRARY_PATH is a workaround, not a solution.

    Why can't you just always use the Firefox nsslib?

    There's a lot of history here. The short story is that Python, Firefox and other system libs need to be compatible for everything to work. On top of this, firefox_decrypt supports the 3 main OSes which have slightly different quirks to them. The libnssutil3.so dependency mentioned above is one example.

  16. 21 remaining items

  17. pepa65 commented on Nov 13, 2025

    @pepa65

    That's the disadvantage of debian-based distros, you're stuck with what the repos offer (in my case, 3.98) unless you compile yourself. But since firefox comes with it's own version, it makes sense to use it (as it was also used to encrypt in the first place).

  18. unode commented on Nov 13, 2025

    @unode
    Owner

    Then for now, the options:

    • LD_LIBRARY_PATH
    • /etc/ld.so.conf.d/firefox-libs.conf
    • Containers 💥 such as ubuntu:questing which includes libnss3 3.114
  19. unode commented on Nov 13, 2025

    @unode
    Owner

    And it looks like more exciting times ahead (sigh).
    Seems like decrypting Firefox 144 profiles with Firefox 145 or 140.5 (ESR) now fails on Linux (exit status 17 not 12) but works fine on Windows.

    I think I'll let the dust settle on this new feature of Firefox 144 profiles and come back to it later.

    Using libnss3 3.113+ is the currently supported option on Linux.

  20. jrw commented on Nov 13, 2025

    @jrw
    Author
    1. @unode Regarding "more exciting times ahead": As long as I'm using the LD_LIBRARY_PATH approach, I have no trouble decrypting my profile which was created long before the current firefox version and has been upgraded for years and is now at version 145.
    2. As @pepa65 mentioned, I can't really upgrade my version of NSS to 3.113+ since this is a system library supplied as a debian package. I don't really understand the scenario of installing libnss3 as a package separate from firefox. Is it ever possible to install a os-packaged firefox where libnss3 is not installed along with firefox? Are you trying to support scenarios where firefox is not installed, or maybe multiple versions of firefox are installed?
    3. Unless I'm badly misunderstanding the scenarios being supported, I think the best approach would be to use the actual libnss3.so library that firefox itself uses, which in my case is /usr/lib/firefox/libnss3.so. However, due to the complications getting CDLL to load the correct versions of the auxillary libraries required by libnss3 (namely libnspr4, libplc4, libplds4, and libnssutil3), this doesn't appear to work unless LD_LIBRARY_PATH is set.
    4. I'm not sure why Firefox's libnss3.so doesn't just use '$ORIGIN' in its RPATH, since the required compatible auxiliary libraries (e.g. libnssutil3.so) come from the same directory as libnss3.so.
    5. Regarding the available workarounds: Using the LD_LIBRARY_PATH=/usr/lib/firefox firefox_decrypt.py approach isolates the required change to just the call to a single program and can be wrapped with a simple script. Updating /etc/ld.so.conf.d/ is a system-wide change, which is too much in my mind. Containers bring in a huge amount of other baggage which is not otherwise needed.
    6. I don't know much about the ctypes module, but it appears that CDLL does not load libraries in a way that allows them to share their resolved symbols. So, when CDLL(libnss3) is called, the references into libnssutil3 will be resolved by the system loader/linker library function (dlopen) from a newly loaded library, rather than using the symbols already loaded in a previous CDLL(libnssutil3) call. Otherwise the code would work when I call:
    # jrw   self.libnss = load_libnss()
            self.libnss1 = ct.CDLL("/usr/lib/firefox/libnspr4.so")
            self.libnss2 = ct.CDLL("/usr/lib/firefox/libplc4.so")
            self.libnss3 = ct.CDLL("/usr/lib/firefox/libplds4.so")
            self.libnss4 = ct.CDLL("/usr/lib/firefox/libnssutil3.so")
            self.libnss = ct.CDLL("/usr/lib/firefox/libnss3.so")
    
  21. unode commented on Nov 13, 2025

    @unode
    Owner
    1. The comment was a remark to the fact that in the CI, the libnss that should be the one bundled with Firefox 145 is loaded but decryption still fails. This doesn't happen on Windows where the same approach to install Firefox 145 is used.
      This made me think that something changed in the way Firefox is packaged and distributed.

    However while writing this message I realised that if another libnss3 lib exists in the CI environment, it could explain the failure. Something to test...

    More to this, I believe Firefox migrates profiles automatically. So if you have an old profile and use a new(er) Firefox to access it, some things will be migrated transparently (e.g. the transition between cert8.db and cert9.db). This is one of the test scenarios as we support Firefox profiles from as far back as version 20.

    1. Firefox bundles it's own libnss3.so (and related libs) but most Linux systems also support installing libnss3 standalone. This has been a supported option since the beginning and has proved to be more reliable than embedded/bundled libs. Especially on other systems (e.g. MacOS) where bundled libs are quite "hidden away". The only downside is that the system lib tends to lag behind and be older, which unfortunately is an obstacle for the issue you are both having.

    2. In your current system, yes, using the bundled libs with LD_LIBRARY_PATH is the most straightforward solution. The need for this is, however and as far as I can tell, a recent change. It used to not be a problem to link directly to bundled libs. They were correctly linked and reliable. I haven't tested other Linux flavours but it seems to no longer be the case in Debian/Ubuntu based distros.
      This could be something to report upstream.

    3. Agree. Can you confirm if older versions did this? If so reporting upstream can be more easily substantiated.

    4. Agree but I don't like to encourage the use of LD_LIBRARY_PATH. It causes too many problems if you need to spawn a different binary and the environment needs to be partially preserved.
      The other option is to use patchelf to modify the lib's RPATH in-place, which avoids depending on LD_LIBRARY_PATH or ld.so.conf.
      This may actually be the most reliable option as you can copy a libnss3.so to your project folder and fix it for your use only. firefox_decrypt already tries to search the current directory, I believe, so this may work without further changes.

    In NixOS this is a very common problem that affects commercial binaries/software. The patchelf tool was created to avoid relying on LD_LIBRARY_PATH.

    Containers are a bazooka when a fly swatter could be sufficient, hence the 💥

    1. I haven't dug that deep either but most of the advice online tends to involve LD_LIBRARY_PATH which is far from ideal.
  22. jrw commented on Nov 14, 2025

    @jrw
    Author
    1. For reference, here are the versions of libnss3 I have on my system. The first two are obviously from OS-installed application packages and the third is the separately-installed OS-package one you're referring to.
    /usr/lib/firefox/libnss3.so
    /usr/lib/thunderbird/libnss3.so
    /usr/lib/x86_64-linux-gnu/libnss3.so
    

    Yeah, MacOS is a pain.

    1. I sort of suspect that libnss3 and maybe libnssutil3 changed or augmented their APIs in a way that they don't work well with the system libnss3 and libnssutil3 anymore.

    2. Not quite sure how to check this. I suppose I could install a VM with an older version of Mint and install Firefox, but avoid upgrading. And then use patchelf or something to pull apart the .so libraries to see what the headers are where RPATH would be to set to see if anything changed between firefox versions.

    3. I definitely agree that having to use LD_LIBRARY_PATH is horrible (I remember reading articles on the web years ago about how evil it is). In this particular case, where no sub-process is created that would be affected by it, it's tolerable. In other cases, like I mentioned above with the oracle instantclient, I've used patchelf to add the appropriate RPATH so that I didn't have to use LD_LIBRARY_PATH. However, LD_LIBRARY_PATH seems to be almost everybody's standard way to deal with this kind of thing. But I definitely don't want to use patchelf on a OS-package-installed library since it would break for every firefox update. I don't think it makes sense to copy it to somewhere else, so that I can stabilize its use with firefox_decrypt because then I would run the risk of it falling behind the actual version used by firefox and not working. Especially when I have a no-problem workaround (LD_LIBRARY_PATH) that doesn't have any downsides (in this particular scenario) for me.

    I agree patchelf is a great tool. I really missed it when I had to fiddle with the oracle instantclient on AIX and use AIX-native tools.

    I agree that using LD_LIBRARY_PATH is far from ideal in the general case, but since firefox_decrypt doesn't create child processes which could be problematic, creating just a wrapper around firefox_decrypt to set LD_LIBRARY_PATH seems to be a simple solution. I think maybe an option to have firefox_decrypt itself serve as the wrapper (by re-exec'ing itself after setting LD_LIBRARY_PATH), maybe under control of an option, might be a good solution to the general problem it is running into.

    Maybe it would work like this:

    • Locate the firefox-installed libnss3 library
    • If LD_LIBRARY_PATH is not already set and --re-exec is specified, then:
      • Set LD_LIBRARY_PATH to the directory containing the library
      • Re-exec firefox_decrypt with the original options
  23. unode commented on Nov 14, 2025

    @unode
    Owner
    1. Looks fine.
    % strings path/to/libnss3.so | grep '^NSS_3' | sort -V | tail -n 1
    NSS_3.116
    

    Allows a quick inspection of what version it may be.

    I also just confirmed that the last path to be checked is now the one resolved by the system so in your case the order you printed is also what firefox_decrypt would use if the previous didn't exist or fails to load.

    1. I used a docker container yesterday. Didn't need to open the Firefox GUI, just to see how the libs looked on disk.

    2. Agree. And even simpler than a wrapper alias ffd="LD_LIBRARY_PATH=... /path/to/firefox_decrypt.py

    On the last point. I didn't try and won't be able to in the next days but can you try to inject LD_LIBRARY_PATH in os.environ before using ctypes.CDLL? If that works there it may avoid the rexec which I'm not keen on.

    EDIT: If the latter works, we can even include that as a default behavior after running the current "try to load every path we can find" approach. On Windows libs load as if you did LD_LIBRARY_PATH=$(pwd) so there we actually change to the lib directory when loading. This doesn't work the same on Linux but the above LD_LIBRARY_PATH workaround could get us that far as well.

  24. jmuhlich commented on Feb 3, 2026

    @jmuhlich

    My python (conda) environment has an older libnss in it but my Snap-provided Firefox 144+ uses the newer version, and neither setting LD_LIBRARY_PATH nor NSS_LIB_PATH nor both to the Snap Firefox's lib path worked. It seems that the libnssutil3.so from the python environment would always conflict and cause the "libnssutil3.so: version `NSSUTIL_3.xxx' not found" error from the dynamic linker when firefox_decrypt tried to load the desired libnss3.so. The only thing that worked was preloading both libnss and libnssutil via LD_PRELOAD:

    LD_PRELOAD=/snap/firefox/current/usr/lib/firefox/libnss3.so:/snap/firefox/current/usr/lib/firefox/libnssutil3.so python3 firefox_decrypt.py ...

    This is a hack, to be sure, but it might help someone get the script working in a pinch.

  25. unode commented on Feb 3, 2026

    @unode
    Owner

    Thanks for the suggestion @jmuhlich

    Looks like we'll need to find a better solution to work with these libraries from Python.

  26. lkraider commented on Aug 24, 2026

    @lkraider

    The root cause in this thread is that ct.CDLL("libnss3.so") loads the system-wide libnss3, and that copy is older than NSS 3.113. NSS 3.113 added the AES-256-CBC support Firefox 144 needs.

    The two workarounds that could work:

    1. LD_LIBRARY_PATH=/usr/lib/firefox firefox_decrypt.py — forces the linker to pick Firefox's own libnss3, which carries a compatible version.
    2. Load Firefox's libnssutil3.so before libnss3.so inside NSSProxy.__init__, so the chained dependency resolves from the same directory.

    Both break when Firefox's library path changes (snap puts it under ~/snap/firefox/, Flatpak under ~/.var/app/).

    On a distro where updating the system libnss3 to 3.113+ is available, that is the clean fix for firefox_decrypt.


    I wrote a separate tool that reads key4.db and logins.json without calling into NSS. It does the PBKDF2 and AES-256-CBC unwrap in its own code and reads the SQLite file format directly. One static binary, no Python, no shared libraries to match. It runs on macOS, Linux and Windows: https://lkraider.github.io/keywise/

  27. unode commented on Aug 25, 2026

    @unode
    Owner

    Thanks @lkraider - reimplementing parts of libnss never felt like a worthwhile effort and was always seen as limiting the use of the tool if the format or encryption changes (as it did with NSS 3.113).

    I guess times changed and some things are easier today...

    As distros update the system libnss3 to newer versions we should slowly stop seeing this problem.
    I've now also prepared firefox_decrypt to be packaged or installed with pixi, pulling libnss3.so from conda-forge::nss.

    git clone https://github.com/unode/firefox_decrypt.git
    cd firefox_decrypt
    pixi run python firefox_decrypt.py
    

    @jrw @jmuhlich @pepa65 feedback is welcome regarding the pixi solution.
    If this works for you I'd consider this issue solved.

  28. jrw commented on Aug 25, 2026

    @jrw
    Author
  29. pepa65 commented on Aug 25, 2026

    @pepa65

    I had never heard of pixi, but I love deploying Rust solutions, except it seems it isn't building at the moment with cargo install --locked pixi... I got it to build locally.

    ./pixi run python firefox_decrypt.py works. But I prefer just LD_LIBRARY_PATH=/usr/lib/firefox firefox_decrypt.py. (Pixi is 139 MB here...)

  30. unode commented on Aug 26, 2026

    @unode
    Owner

    Thanks for the patience everyone.

    Based on the feedback and the mentioned workarounds, I'll consider this issue solved for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions