Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add method to load login credentials as well as cookies #164

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

dlenski
Copy link
Contributor

@dlenski dlenski commented Apr 16, 2023

The machinery for decrypting login credentials on Chromium-based browsers is
essentially identical to what's used to decrypt cookies. For a fairly hacky
standalone implementation of login credential decryption, see
https://github.com/priyankchheda/chrome_password_grabber.

Done:

  • Add ChromiumBased.load_logins() method.
  • Autodetect paths for login credentials on Chrome and Chromium browsers on
    Linux. (Tested both)

TODO:

  • Determine correct paths for login credentials on Windows, macOS, and other
    Chromium-based browsers.

    For now, you should be able to test whether the same decryption process
    works by finding the login credentials database path, and passing passing
    login_file='THAT_PATH' to the constructor for any ChromiumBased
    browser.

  • Add loading and decryption of login credentials from Firefox as well.
    Perhaps based on https://github.com/unode/firefox_decrypt?

This takes up time and disk space unnecessarily.

SQLite3 is able to open databases in a read-only, lock-free mode (see
"nolock" in https://www.sqlite.org/c3ref/open.html).  Tested on Linux with
Chrome, Chromium, and Firefox; loading cookies from databases opened in
these modes appear to work fine as long as we attempt to fallback from
read-only, lock-free to simply read-only.

Somewhat frustratingly and confusingly, these option seems only to be
accessible by using 'file:' URIs, and not via any other API (see
https://www.codejam.info/2021/10/bypass-sqlite-exclusive-lock.html).

Fortunately, the standard library module pathlib (Python 3.4+) makes it easy
to convert paths to 'file:' URIs in a cross-platform way.
The replacement of sqlite3 with pysqlite2 on Windows dates back to the
initial 2015 commit to the parent repository
(richardpenman/browsercookie@7828992).

pysqlite2 is no longer maintained, and there no longer appears to be any bug
or limitation preventing sqlite3 from opening Chrome/Firefox databases on
Windows.
This same idiosyncratic timestamp format ("microseconds since Windows NT
epoch") is apparently used by Chromium-based browsers for both cookies’
expiration timestamps, as well as timestamps associated with saved login
credentials.
@dlenski dlenski force-pushed the login_credentials branch 2 times, most recently from 8ef18de to 217d331 Compare April 16, 2023 04:29
The machinery for decrypting login credentials on Chromium-based browsers is
essentially identical to what's used to decrypt cookies.  For a fairly hacky
standalone implementation of login credential decryption, see
https://github.com/priyankchheda/chrome_password_grabber.

Done:

- Add ChromiumBased.load_logins() method.
- Autodetect paths for login credentials on Chrome and Chromium browsers on
  Linux. (Tested both)

TODO:

- Determine correct paths for login credentials on Windows, macOS, and other
  Chromium-based browsers.

  For now, you should be able to test whether the same decryption process
  works by finding the login credentials database path, and passing passing
  `login_file='THAT_PATH'` to the constructor for any `ChromiumBased`
  browser.
- Add loading and decryption of login credentials from Firefox as well.
  Perhaps based on https://github.com/unode/firefox_decrypt?
@rafiibrahim8
Copy link
Collaborator

Hi @dlenski,
Is it okay if I merge this PR? And close PR #163?

@dlenski
Copy link
Contributor Author

dlenski commented Apr 17, 2023

And close PR #163?

You should probably merge that one first, since it just makes small cleanup-y changes…

Is it okay if I merge this PR?

You could, but I've only tested in on recent Chrome/Chromium on Linux, and not even sure if it'll work with other versions of Chrom*-based browsers or on other OSes. And additional work for Firefox is certainly needed.

I mostly wanted to post it at this point in order to get feedback on the interface/API for loading the logins.

@rafiibrahim8
Copy link
Collaborator

Your approach looks good to me. I can test them on different browsers and OSes.
I'm going to merge it and then add other browsers after done testing. It that sound okay?

rafiibrahim8 and others added 5 commits October 4, 2023 08:10
No file copying, and no Windows import override needed
The machinery for decrypting login credentials on Chromium-based browsers is
essentially identical to what's used to decrypt cookies.  For a fairly hacky
standalone implementation of login credential decryption, see
https://github.com/priyankchheda/chrome_password_grabber.

Done:

- Add ChromiumBased.load_logins() method.
- Autodetect paths for login credentials on Chrome and Chromium browsers on
  Linux. (Tested both)

TODO:

- Determine correct paths for login credentials on Windows, macOS, and other
  Chromium-based browsers.

  For now, you should be able to test whether the same decryption process
  works by finding the login credentials database path, and passing passing
  `login_file='THAT_PATH'` to the constructor for any `ChromiumBased`
  browser.
- Add loading and decryption of login credentials from Firefox as well.
  Perhaps based on https://github.com/unode/firefox_decrypt?
Also:

- Put source package in a directory called browser_cookie3, so
  that __main__.py can 'from .  import *' even while testing
- Clean up/clarify BrowserCookieError() messages a bit
- Make Firefox class and firefox() function take a key_file parameter, but
  ignore it, for a consistent interface with Chromium-based browsers
- Cleanup all trailing whitespace (with https://github.com/dlenski/wtf)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants