Giter Site home page Giter Site logo

n8henrie / pycookiecheat Goto Github PK

View Code? Open in Web Editor NEW
671.0 26.0 107.0 212 KB

Borrow cookies from your browser's authenticated session for use in Python scripts.

Home Page: https://n8henrie.com/2013/11/use-chromes-cookies-for-easier-downloading-with-python-requests/

License: MIT License

Python 95.08% Nix 4.92%
python3 chrome cookies requests

pycookiecheat's Introduction

pycookiecheat

master branch build status

Borrow cookies from your browser's authenticated session for use in Python scripts.

Installation

NB: Use pip and python instead of pip3 and python3 if you're still on Python 2 and using pycookiecheat < v0.4.0. pycookiecheat >= v0.4.0 requires Python 3 and in general will aim to support python versions that are stable and not yet end-of-life: https://devguide.python.org/versions.

  • python3 -m pip install pycookiecheat

Installation notes regarding alternative keyrings on Linux

See #12. Chrome is now using a few different keyrings to store your Chrome Safe Storage password, instead of a hard-coded password. Pycookiecheat doesn't work with most of these so far, and to be honest my enthusiasm for adding support for ones I don't use is limited. However, users have contributed code that seems to work with some of the recent Ubuntu desktops. To get it working, you may have to sudo apt-get install libsecret-1-dev python-gi python3-gi, and if you're installing into a virtualenv (highly recommended), you need to use the --system-site-packages flag to get access to the necessary libraries.

Alternatively, some users have suggested running Chrome with the --password-store=basic or --use-mock-keychain flags.

Development Setup

  1. git clone https://github.com/n8henrie/pycookiecheat.git
  2. cd pycookiecheat
  3. python3 -m venv .venv
  4. ./.venv/bin/python -m pip install -e .[dev]

Usage

from pycookiecheat import BrowserType, chrome_cookies
import requests

url = 'https://n8henrie.com'

# Uses Chrome's default cookies filepath by default
cookies = chrome_cookies(url)
r = requests.get(url, cookies=cookies)

# Using an alternate browser
cookies = chrome_cookies(url, browser=BrowserType.CHROMIUM)

Use the cookie_file keyword-argument to specify a different filepath for the cookies-file: chrome_cookies(url, cookie_file='/abspath/to/cookies')

You may be able to retrieve cookies for alternative Chromium-based browsers by manually specifying something like "/home/username/.config/BrowserName/Default/Cookies" as your cookie_file.

Features

  • Returns decrypted cookies from Google Chrome, Brave, or Slack, on MacOS or Linux.
  • Optionally outputs cookies to file (thanks to Muntashir Al-Islam!)

FAQ / Troubleshooting

How about Windows?

I don't use Windows or have a PC, so I won't be adding support myself. Feel free to make a PR :)

I get an installation error with the cryptography module on OS X

(pycookiecheat <v0.4.0)

If you're getting this error and using Homebrew, then you need to follow the instructions for Building cryptography on OS X and export LDFLAGS="-L$(brew --prefix openssl)/lib" CFLAGS="-I$(brew --prefix openssl)/include" and try again.

I get an installation error with the cryptography module on Linux

Please check the official cryptography docs. On some systems (e.g. Ubuntu), you may need to do something like sudo apt-get install build-essential libssl-dev libffi-dev python-dev prior to installing with pip.

How can I use pycookiecheat on KDE-based Linux distros?

On KDE, Chrome defaults to using KDE's own keyring, KWallet. For pycookiecheat to support KWallet the dbus-python package must be installed.

How do I install the dev branch with pip?

  • python -m pip install git+https://github.com/n8henrie/pycookiecheat@dev

Buy Me a Coffee

☕️

pycookiecheat's People

Contributors

alairock avatar ankostis avatar brandon-rhodes avatar chrisgavin avatar dependabot[bot] avatar dgruano avatar glutanimate avatar grandchild avatar hraftery avatar jtbraun avatar muntashirakon avatar n8henrie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pycookiecheat's Issues

valueError: Namespace Secret not available

I am trying to run a flask application in a docker container . This application uses pycookiecheat to obtain chrome cookies for a login. The app works well when it is on my machine. But i am getting these errors when i am running it on a container

Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 2309, in call
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/dist-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/dist-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functionsrule.endpoint
File "/app/flaskapp.py", line 25, in query_submit
cookies = chrome_cookies(url)
File "/usr/local/lib/python3.6/dist-packages/pycookiecheat/pycookiecheat.py", line 169, in chrome_cookies
config = get_linux_config(browser)
File "/usr/local/lib/python3.6/dist-packages/pycookiecheat/pycookiecheat.py", line 122, in get_linux_config
gi.require_version('Secret', '1')
File "/usr/lib/python3/dist-packages/gi/init.py", line 127, in require_version
raise ValueError('Namespace %s not available' % namespace)

Windows support

Thank you for your very convenient utility.

Would it be possible to decrypt cookies also on Window Chrome?

Syntax error on line 27

Hi, I'm getting this error when trying to use pycookiecheat

[...]
pycookiecheat.py", line 27
    def clean(decrypted: bytes) -> str:
                       ^
SyntaxError: invalid syntax

I'm using MacOS Sierra (10.12.6) with Python2.7 inside virtualenv and pycookiecheat installed with pip

browser = Slack now gives "TypeError: key_material must be bytes-like"

  • Operating system and version: macOS 13.4.1 (c)
  • Python version: 3.11.4
  • pycookiecheat version: 0.5.2

My Issue

The addition I made (adding "Slack" to the list of support browsers) has stopped working, on macOS at least. The error seems mysterious:

>>> cookies = pycookiecheat.chrome_cookies("http://slack.com", browser="Slack")
Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.11/site-packages/cryptography/utils.py", line 34, in _check_byteslike
    memoryview(value)
TypeError: memoryview: a bytes-like object is required, not 'NoneType'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/homebrew/lib/python3.11/site-packages/pycookiecheat/pycookiecheat.py", line 249, in chrome_cookies
    enc_key = kdf.derive(config["my_pass"])
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.py", line 55, in derive
    utils._check_byteslike("key_material", key_material)
  File "/opt/homebrew/lib/python3.11/site-packages/cryptography/utils.py", line 36, in _check_byteslike
    raise TypeError("{} must be bytes-like".format(name))
TypeError: key_material must be bytes-like

WHYT

Turns out the root issue is way back at this line:

"my_pass": keyring.get_password("{} Safe Storage".format(browser), browser)

which seems to quietly (without even prompting for a password) return nothing if the second parameter doesn't have a match. keyring calls the parameters service_name and username but in Keychain Access at least they seem to be called "Name" and "Account".

Anyway, point is the "Account" seems to have changed from "Slack" to "Slack Key". That's it!

So a hacky fix is to change the line to something like:

"my_pass": keyring.get_password("{} Safe Storage".format(browser), "Slack Key" if browser == "Slack" else browser)

but I'll have to think a bit more about actually doing it properly.

cookies expire in day or in random time

  • Operating system and version: Fedora 33
  • Python version:python 3.7
  • pycookiecheat version: master branch

My Issue

cookies expire in day or in random time

WHYT


Please make sure you've taken these steps before submitting a new issue:

  • Include the Python and pycookiecheat version in your issue
  • Ensure you're running a supported version of Python
  • Run pycookiecheat in debug mode if applicable and include
    relevant output
  • Search the existing (including closed) issues
  • Please use codeblocks for any code, config, program output, etc.

chrome v96.0.4664.93 Cookie file is not in 'Google\Chrome Dev\User Data\Default\Cookies'

this is my code

# -*- coding:'utf-8' -*-
import time,traceback,sqlite3,os,json,base64,sys

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher
from cryptography.hazmat.primitives.ciphers.algorithms import AES
from cryptography.hazmat.primitives.ciphers.modes import CBC
from cryptography.hazmat.primitives.hashes import SHA1
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.ciphers.aead import AESGCM


def decryptString(key,data):
    iv = data[3:15]
    cipherbytes = data[15:]
    aesgcm=AESGCM(key)
    plainbytes=aesgcm.decrypt(iv, cipherbytes, None)
    plaintext=plainbytes.decode('utf-8')
    return plaintext

def getKey():
    LocalState = ''
    if (os.path.exists(os.environ['LOCALAPPDATA']+r"\Google\Chrome\User Data\Local State")):
      LocalState  = os.environ['LOCALAPPDATA']+r"\Google\Chrome\User Data\Local State"
    elif (os.path.exists(os.environ['LOCALAPPDATA']+r"\Google\Chrome Dev\User Data\Local State")):
      LocalState  = os.environ['LOCALAPPDATA']+r"\Google\Chrome Dev\User Data\Local State"
    else:
      raise Exception('not found Cookie file!')

    with open(LocalState, 'r', encoding='utf-8') as f:
        base64_encrypted_key = json.load(f)['os_crypt']['encrypted_key']

    from win32crypt import CryptUnprotectData
    encrypted_key_with_header=base64.b64decode(base64_encrypted_key)
    encrypted_key=encrypted_key_with_header[5:] 
    key = CryptUnprotectData(encrypted_key,None,None,None,0)[1]
    # mykey = base64.b64encode(key)
    return key


def getChromeCookie(hostsUrl):
    cookiepath = ''
    if (os.path.exists(os.environ['LOCALAPPDATA']+r"\Google\Chrome\User Data\Default\Cookies")):
      cookiepath  = os.environ['LOCALAPPDATA']+r"\Google\Chrome\User Data\Default\Cookies"
    elif (os.path.exists(os.environ['LOCALAPPDATA']+r"\Google\Chrome Dev\User Data\Default\Cookies")):
      cookiepath  = os.environ['LOCALAPPDATA']+r"\Google\Chrome Dev\User Data\Default\Cookies"
    else: 
      raise Exception('not found Cookie file!')

    sql = f"select name,encrypted_value from cookies where host_key = '{hostsUrl}'"
  
    try:
        conn = sqlite3.connect(cookiepath)
        conn.text_factory =  bytes 
        res=conn.execute(sql).fetchall()
        conn.close()
    except Exception as e:
        print(e)
    key = getKey()
    row = res.pop()
    # cookieList.append( f'{str(row[0],encoding = "utf-8")}={decryptString(key, row[1])}')
    return f'{decryptString(key, row[1])}'


def clean(decrypted: bytes) -> str:
    last = decrypted[-1]
    if isinstance(last, int):
        return decrypted[:-last].decode("utf8")
    return decrypted[: -ord(last)].decode("utf8")


def chrome_decrypt(encrypted_value: bytes, key: bytes, init_vector: bytes):
  encrypted_value = encrypted_value[3:]
  cipher = Cipher(algorithm=AES(key), mode=CBC(init_vector), backend=default_backend())
  decryptor = cipher.decryptor()
  decrypted = decryptor.update(encrypted_value) + decryptor.finalize()
  return clean(decrypted)

def chrome_cookies(url: str, browser: str = "Chrome",):
    import keyring

    file_path = ''
    if (os.path.exists(os.path.expanduser('~/Library/Application Support/Google/Chrome/Default/Extension Cookies'))):
      file_path  = os.path.expanduser('~/Library/Application Support/Google/Chrome/Default/Extension Cookies')
    elif (os.path.exists(os.path.expanduser('~/Library/Application Support/Chromium/Default/Cookies'))):
      file_path  = os.path.expanduser('~/Library/Application Support/Chromium/Default/Cookies')
    elif (os.path.exists(os.path.expanduser('~/Library/Application Support/Google/Chrome Dev/Default/Cookies'))):
      file_path  = os.path.expanduser('~/Library/Application Support/Google/Chrome Dev/Default/Cookies')
    else:
      raise Exception('not found Cookie file!')

    config = {
        "my_pass": keyring.get_password(
            "{} Safe Storage".format(browser), browser
        ),
        "iterations": 1003,
        "cookie_file": file_path,
        "init_vector": b" " * 16,
        "length": 16,
        "salt": b"saltysalt"
    }
    
    if isinstance(config["my_pass"], str):
      config["my_pass"] = config["my_pass"].encode("utf8")

    kdf = PBKDF2HMAC(
        algorithm=SHA1(),
        backend=default_backend(),
        iterations=config["iterations"],
        length=config["length"],
        salt=config["salt"],
    )
    enc_key = kdf.derive(config["my_pass"])

    
    try:
        conn = sqlite3.connect(config["cookie_file"])
    except sqlite3.OperationalError:
        print("Unable to connect to cookie_file at: {}\n".format(config["cookie_file"]))
        raise

    sql = ("select name, encrypted_value from cookies where host_key like ?")

    cookies = ''

    for item in conn.execute(sql, (url,)).fetchall():
        cookies = chrome_decrypt(item[1], key=enc_key, init_vector=config["init_vector"])

    conn.rollback()

    return cookies


def getCookie(url):
  # mac
  if sys.platform == "darwin":
    return chrome_cookies(url)
  # windows
  elif sys.platform == 'win32':
    return getChromeCookie(url)

obj = {
  "Authorization": getCookie('pass.didapinche.com'),
}
print(json.dumps(obj))

Depend on pycryptodome instead of pycrypto

This package should depend on pycryptodome instead of pycrypto, as it is a actively maintained drop-in replacement for pycrypto. Pycrypo has issues installing on Windows, and hasn't been maintained since ~2013.

Due to the install issue I'm having to temporarily fork this library, since overriding dependencies is apparently quite difficult to do.

Get AttributeError Only with crontab

I wrote a python program using pycookiecheat.
When I run it with the command python myprogram.py, it will run successfully.
However, I run it in crontab with the config below:

* * * * * /usr/bin/python  /Users/fatghosta/workspace/myprogram.py >> /Users/fatghosta/workspace/myprogram.log

I get some error below:

Traceback (most recent call last):
  File "/Users/fatghosta/workspace/myprogram.py", line 33, in <module>
    cookies = chrome_cookies("http://xx.xxx.com")
  File "/Library/Python/2.7/site-packages/pycookiecheat-0.2.0-py2.7.egg/pycookiecheat/pycookiecheat.py", line 61, in chrome_cookies
    my_pass = my_pass.encode('utf8')
AttributeError: 'NoneType' object has no attribute 'encode'

My OS version is OS X 10.10.5.
I setup pycookiecheat by cloning pycookiecheat.git and then "python setup.py install".

Malformed database schema

When running the example, I get
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "./pycookiecheat/pycookiecheat.py", line 93, in chrome_cookies for k, v, ev in conn.execute(sql, (host_key,)): sqlite3.DatabaseError: malformed database schema (is_transient) - near "where": syntax error

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb9 in position 3: invalid start byte

  • Operating system and version: fedora 32
  • Python version: 3.8
  • pycookiecheat version: pycookiecheat-0.4.5

My Issue

facing issue on UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb9 in position 3: invalid start byte

[Praveen@praveenpenguin setup]$ python s.py
Traceback (most recent call last):
File "s.py", line 8, in
cookies = chrome_cookies(url)
File "/usr/local/lib/python3.8/site-packages/pycookiecheat/pycookiecheat.py", line 279, in chrome_cookies
val = chrome_decrypt(
File "/usr/local/lib/python3.8/site-packages/pycookiecheat/pycookiecheat.py", line 71, in chrome_decrypt
return clean(decrypted)
File "/usr/local/lib/python3.8/site-packages/pycookiecheat/pycookiecheat.py", line 44, in clean
return decrypted[:-last].decode("utf8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb9 in position 3: invalid start byte
[Praveen@praveenpenguin setup]$

[Praveen@praveenpenguin setup]$ cat s.py
from pycookiecheat import chrome_cookies
import requests

url = 'http://www.google.com'

Uses Chrome's default cookies filepath by default

cookies = chrome_cookies(url)
r = requests.get(url, cookies=cookies)

print (r)
[Praveen@praveenpenguin setup]$


Please make sure you've taken these steps before submitting a new issue:

  • Include the Python and pycookiecheat version in your issue
  • Ensure you're running a supported version of Python
  • Run pycookiecheat in debug mode if applicable and include
    relevant output
  • Search the existing (including closed) issues
  • Please use codeblocks for any code, config, program output, etc.

sqlite3.OperationalError: database is locked

  • Operating system and version: macOS 10.13.6
  • Python version: 3.7.4
  • pycookiecheat version: v0.4.5

After making a few thousand of requests, it gives error

...pycookiecheat.py, line 273, in chrome_cookies
   ) in conn.execute(sql, (host_key,)):
sqlite3.OperationalError: database is locked

A work-around is to close Chrome and re-open Chrome to be able to continue making more requests.

WHYT


Please make sure you've taken these steps before submitting a new issue:

  • Include the Python and pycookiecheat version in your issue
  • Ensure you're running a supported version of Python
  • Run pycookiecheat in debug mode if applicable and include
    relevant output
  • Search the existing (including closed) issues
  • Please use codeblocks for any code, config, program output, etc.

A question

simple ask a question. The cookie will be writed back by chrome whenever the value of cookie changed ? Or just when I close chrome.

Provide a command-line tool

I think this library is a good candidate for a command line tool, ideally including an option to export to something like a netscape cookie file that tools like curl or youtube-dl can read (I think it requires some kind of header-as-a-comment for the latter).

Expedia post request to get hotel list

I am trying to get list of hotels for a particular location in expedia. But i get a 400 bad request. Although i am able to make request from Chromium console i am getting 400 bad request when a make it from scrapy.

import scrapy
import pdb
from scrapy.http.cookies import CookieJar
from pycookiecheat import chrome_cookies

class ExpediaHotelSpider(scrapy.Spider):
"""Expedia spider"""
name = "expediaspider"
allowed_domains = ["expedia.co.in"]
start_urls = ["https://www.expedia.co.in/Hotel-Search"]

def parse(self, response):
    cookies = chrome_cookies('https://www.expedia.co.in/Hotel-Search')
    request = scrapy.FormRequest(url='https://www.expedia.co.in/Hotel-Search?inpAjax=true&responsive=true&origin=HOT:SR:UpdateSearch',
                cookies=cookies,
                formdata={  'adults': '1',
                            'destination': 'Bengaluru (and vicinity), India',
                            'endDate': '16/02/2016',
                            'startDate': '15/02/2016',
                            'sort': 'recommended',
                            'regionId':'6053307',
                            'hashParam':'2035b06478adf2e9364eb7ce702f5d86ac136201'
                            }, method='POST',
                callback='parse_1')
    return [request]

def parse_1(self, response):
    pdb.set_trace()

UnicodeDecodeError: 'utf-8' codec can't decode byte in `clean` function

Hi, @n8henrie , I found this error when I use pycookiecheat

my machine version info:
Linux version 4.9.43-1-MANJARO (builduser@manjaro) (gcc version 7.1.1 20170630 (GCC) ) #1 SMP PREEMPT Sun Aug 13 20:28:47 UTC 2017
google-chrome version:
60.0.3112.101 (Official Build) (64-bit)

here's my test code:

import requests
from pycookiecheat import chrome_cookies


if __name__ == '__main__':
      url = 'https://www.google.com'
      cookies = chrome_cookies(url)

hers's traceback:

➜  crawer git:(master) ✗ python pycookietest.py 
Traceback (most recent call last):
  File "pycookietest.py", line 7, in <module>
    cookies = chrome_cookies(url)
  File "/usr/lib/python3.6/site-packages/pycookiecheat/pycookiecheat.py", line 216, in chrome_cookies
    init_vector=config['init_vector'])
  File "/usr/lib/python3.6/site-packages/pycookiecheat/pycookiecheat.py", line 64, in chrome_decrypt
    return clean(decrypted)
  File "/usr/lib/python3.6/site-packages/pycookiecheat/pycookiecheat.py", line 41, in clean
    return decrypted[:-last].decode('utf8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbe in position 0: invalid start byte

And I also research the issue #12
I was wondering if the value of my_pass is wrong, so I print every detail in decrypt process
here's return:

encrypted_value:  b'v11\n?r\xec\xcb\x8f\x8f\x1c\x08\x05A 8\xec\x81N~7\xc1O\xa0\xc0\xdd\xbb\xfb\xaa=\xfb\x90\xbd\x1f$'
unlocked_keyring:  []
my_pass:  peanuts
decrypted_value:  b's\t\xdd\xf6mp\x97\x12v\xcf\xd7\x9b\x1c\x83\xf5;\xdd\xa1\xf5\xf5\xe0!S\xb9\xa4\x85C\xbc\xb4\x8b\x93A'
clean_decrypted_value:  

unlocked_keyring was got from your code
clean_decrypted_value is ues clean() function got.
Some clean_decrypted_value is None, some are runs faild, and got the same log UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbe in position 0: invalid start byte.

Please help me figure this out. Thanks!

BTW, forgive my poor English...

Windows alternative ?

  • Operating system and version:
    Windows 10
  • Python version:
    3.11.5
  • pycookiecheat version:
    latest 0.5.0

My Issue

Need an aproach that works on windows too

[WHYT]

I've edited the code to try to open the Cookies file (its in %LocalAppData%\Google\Chrome\User Data\Default\Network\Cookies btw)
but im having no luck
current code:

      # ...
      # inside: def chrome_cookies
      # ...
      elif sys.platform == 'win32':
       # Try to get Chrome password from Windows Credential Manager
      try:
        my_pass = keyring.get_password('Chrome Safe Storage', 'Chrome')
        if my_pass is None:
            my_pass = '' 
        else:
            my_pass = my_pass.encode('utf8')
      except keyring.errors.PasswordDeleteError:
        # No saved password, use empty string
        my_pass = ''.encode('utf8')
      iterations = 1
      cookie_file = os.path.expanduser(
        r'%LocalAppData%\Google\Chrome\User Data\Default\Network\Cookies')
      config = {
        'my_pass': b'',  # Default to an empty password
        'iterations': 1,
        'cookie_file': os.path.expandvars(r'%LocalAppData%\Google\Chrome\User Data\Default\Network\Cookies'),
        }
    else:
        raise OSError("This script only works on OSX or Linux.")

    config.update(
        {"init_vector": b" " * 16, "length": 16, "salt": b"saltysalt"}
    )

    if cookie_file:
        cookie_file = str(pathlib.Path(cookie_file).expanduser())
    else:
        cookie_file = str(pathlib.Path(config["cookie_file"]).expanduser())

    if isinstance(password, bytes):
        config["my_pass"] = password
    elif isinstance(password, str):
        config["my_pass"] = password.encode("utf8")
    elif isinstance(config["my_pass"], str):
        config["my_pass"] = config["my_pass"].encode("utf8")

    kdf = PBKDF2HMAC(
        algorithm=SHA1(),
        iterations=config["iterations"],
        length=config["length"],
        salt=config["salt"],
    )
    enc_key = kdf.derive(config["my_pass"])

    try:
        /# Make temp copy to prevent file locking errors  
        #temp_cookie_file = tempfile.NamedTemporaryFile(delete=False)
        #shutil.copyfile(cookie_file, temp_cookie_file.name)
        #conn = sqlite3.connect(temp_cookie_file.name) 
        #conn = sqlite3.connect(cookie_file)
        #conn = sqlite3.connect("file:{}?mode=ro".format(cookie_file), uri=True)
        if not os.path.exists(cookie_file):
            print("Cookie file not found, exiting...")
        else:
            print(" ::: Found FILE! :",cookie_file)
        conn = sqlite3.connect(cookie_file)
        
        #...... rest of program
        

    except sqlite3.OperationalError:
        print("Unable to connect to cookie_file at: {}\n".format(cookie_file))
        raise

output:

 ::: Found FILE! : C:/Users/User/AppData/Local/Google/Chrome/User Data/Default/Network
Unable to connect to cookie_file at: C:/Users/User/AppData/Local/Google/Chrome/User Data/Default/Network

Traceback (most recent call last):
  File "C:\Users\User\Desktop\transparent-web-app\pycookiecheat\src\pycookiecheat\winrun.py", line 23, in <module>
    cookies = chrome_cookies(url, config)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\Desktop\transparent-web-app\pycookiecheat\src\pycookiecheat\pycookiecheat.py", line 314, in chrome_cookies
    conn = sqlite3.connect(cookie_file)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.OperationalError: unable to open database file


# am i doing something wrong? `file:{}?mode=ro` isn't working 

In General, is anyone familar with an alternative working solution on win?
Thanks a lot, greatly apreciated

Enhancement: support the Slack app's cookies

  • Operating system and version:

macOS 11.6.5 and Linux Mint 20

  • Python version:

3.9.12 and 3.8.10

  • pycookiecheat version:

v0.4.7 and master head.

My Issue

The Slack desktop app uses the same cookie storage mechanism as Chrome and Chromium, and there appears to be no more advanced tool for Cookie extraction than pycookiecheat. Although the use cases for extracting cookies from a browser (ie. to browse web pages) might be slightly different to the use cases for extracting cookies from Slack (ie. to access the Slack API manually), the modification to allow pycookiecheat to do both turns out to be really small.

After much consideration about whether to diverge or merge, I believe the best option is to generalise pycookiecheat's functionality slightly, and keep it as the best resource for cookie extraction.

WHYT

Simply passing "Slack" as the browser parameter and Slack's cookie file as the cookie_file parameter to chrome_cookies() results in the misleading "UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb9 in position 3: invalid start byte" type errors. It turns out this is simply because the wrong password is pulled from the keyring. All that needs to change for this to work is to point to a different keyring. Specifying the correct cookie_file can easily be achieved using the existing interface, but specifying the keyring name cannot.

By simply allowing "Slack" as a browser name, the keyring name is correctly determined on macos. The story is a bit more complicated on Linux (tested with some effort on Linux Mint), but turns out to provide a more robust keyring determination method in general anyway.

Thus, I'd like to offer the improvements in a pull request, in the hope that they find their way to PyPI. The relevant commit is here.


Please make sure you've taken these steps before submitting a new issue:

  • Include the Python and pycookiecheat version in your issue
  • Ensure you're running a supported version of Python
  • Run pycookiecheat in debug mode if applicable and include
    relevant output
  • Search the existing (including closed) issues
  • Please use codeblocks for any code, config, program output, etc.

Syntax Error

I'm attempting to run this code

`
from pycookiecheat import chrome_cookies
import requests

url = 'https://www.google.com'

cookies = chrome_cookies(url)
r = requests.get(url, cookies=cookies)

`

Upon doing so, I get this error:

root@Computer:~/PycharmProjects/Test# python Test.py
Traceback (most recent call last):
File "Test.py", line 1, in
from pycookiecheat import chrome_cookies
File "/usr/local/lib/python2.7/dist-packages/pycookiecheat/init.py", line 3, in
from pycookiecheat.pycookiecheat import chrome_cookies # noqa
File "/usr/local/lib/python2.7/dist-packages/pycookiecheat/pycookiecheat.py", line 27
def clean(decrypted: bytes) -> str:
^
SyntaxError: invalid syntax

default password isn't always set

So I don't store any passwords in chromium and have never set a master password. I don't use gnome-keyring for anything, but it's installed. pycookiecheat fails because no "my_pass" key gets set in the config dict. The default key only gets set if this try block fails:

try:
    import gi
    gi.require_version('Secret', '1')
    from gi.repository import Secret
except ImportError:
    config['my_pass'] = 'peanuts'

In my case, the try block executes fine. However, there just isn't any "Chrome Safe Storage" in the keyring. In fact, there seems to be nothing in it (the outer loop iterates over one item, but there are no items for the inner loop to iterate in my case):

else:
    flags = Secret.ServiceFlags.LOAD_COLLECTIONS
    service = Secret.Service.get_sync(flags)

    gnome_keyring = service.get_collections()
    unlocked_keyrings = service.unlock_sync(gnome_keyring).unlocked

    for unlocked_keyring in unlocked_keyrings:
        for item in unlocked_keyring.get_items():
            if item.get_label() == "Chrome Safe Storage":
                item.load_secret_sync()
                config['my_pass'] = item.get_secret().get_text()
                break
        else:
            # Inner loop didn't `break`, keep looking
            continue

        # Inner loop did `break`, so `break` outer loop
        break

I tried the following and now everything works great:

def get_linux_config() -> dict:
    config = dict()  # type: Dict[str, Any]
    config.update({
        'my_pass': 'peanuts',
        'iterations': 1,
        'cookie_file': '~/.config/chromium/Default/Cookies',
        })
    return config

So the problem seems to be that the default password is not set by... default.

Thanks for your script!

Warning messages could be very helpful

Like many others I got the error: "UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb9 in position 3: invalid start byte".

In the very end I had two issues. 1) I had set "Chrome" instead of "Chromium" as the browser. 2) I had not installed "gi".

But it was only after I spent quite some time looking into your source code and injecting my own print statements that I was able to figure things out :)

In my case it could have looked something like:

WARNING: Could not import gi. Using keyring as fallback.
WARNING: Could not find matching key using keyring. Using default Linux secret "peanuts", which works on some setups. 
ERROR: Decoding with utf-8 of decrypted value failed. This is most likely because the encryption was run with incorrect key. 

Sincerely

Firefox support wanted?

My Issue

I'd like to add Firefox support, and want to gauge interest.

WHYT

I have implemented a basic Firefox cookie retrieval method that even works while Firefox is running (which has a lock on the cookies.sqlite DB).

  • Would you be interested in a PR adding this feature?
  • If yes, would you prefer I add a new source file (currently it's all one python file)?

chrome_cookies(url) : UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc0 in position 0: invalid start byte

###Google Chrome : Version 73.0.3683.75 (Official Build) (64-bit)

python version 3.7

centos-release-7-6.1810.2.el7.centos.x86_64

This is how i installed it :
########################################################################
(base) [msingh@centos Python Epiphanies]$ pip install git+https://github.com/n8henrie/pycookiecheat.git
Collecting git+https://github.com/n8henrie/pycookiecheat.git
Cloning https://github.com/n8henrie/pycookiecheat.git to /tmp/pip-req-build-ubqjkpwe
Running command git clone -q https://github.com/n8henrie/pycookiecheat.git /tmp/pip-req-build-ubqjkpwe
Requirement already satisfied (use --upgrade to upgrade): pycookiecheat==0.4.4 from git+https://github.com/n8henrie/pycookiecheat.git in /home/msingh/anaconda3/lib/python3.7/site-packages
Requirement already satisfied: keyring==16.1.0 in /home/msingh/anaconda3/lib/python3.7/site-packages (from pycookiecheat==0.4.4) (16.1.0)
Requirement already satisfied: pycrypto==2.6.1 in /home/msingh/anaconda3/lib/python3.7/site-packages (from pycookiecheat==0.4.4) (2.6.1)
Requirement already satisfied: secretstorage; sys_platform == "linux" and python_version >= "3.5" in /home/msingh/anaconda3/lib/python3.7/site-packages (from keyring==16.1.0->pycookiecheat==0.4.4) (3.1.1)
Requirement already satisfied: entrypoints in /home/msingh/anaconda3/lib/python3.7/site-packages (from keyring==16.1.0->pycookiecheat==0.4.4) (0.3)
Requirement already satisfied: cryptography in /home/msingh/anaconda3/lib/python3.7/site-packages (from secretstorage; sys_platform == "linux" and python_version >= "3.5"->keyring==16.1.0->pycookiecheat==0.4.4) (2.6.1)
Requirement already satisfied: jeepney in /home/msingh/anaconda3/lib/python3.7/site-packages (from secretstorage; sys_platform == "linux" and python_version >= "3.5"->keyring==16.1.0->pycookiecheat==0.4.4) (0.4)
Requirement already satisfied: cffi!=1.11.3,>=1.8 in /home/msingh/anaconda3/lib/python3.7/site-packages (from cryptography->secretstorage; sys_platform == "linux" and python_version >= "3.5"->keyring==16.1.0->pycookiecheat==0.4.4) (1.12.3)
Requirement already satisfied: six>=1.4.1 in /home/msingh/anaconda3/lib/python3.7/site-packages (from cryptography->secretstorage; sys_platform == "linux" and python_version >= "3.5"->keyring==16.1.0->pycookiecheat==0.4.4) (1.12.0)
Requirement already satisfied: asn1crypto>=0.21.0 in /home/msingh/anaconda3/lib/python3.7/site-packages (from cryptography->secretstorage; sys_platform == "linux" and python_version >= "3.5"->keyring==16.1.0->pycookiecheat==0.4.4) (0.24.0)
Requirement already satisfied: pycparser in /home/msingh/anaconda3/lib/python3.7/site-packages (from cffi!=1.11.3,>=1.8->cryptography->secretstorage; sys_platform == "linux" and python_version >= "3.5"->keyring==16.1.0->pycookiecheat==0.4.4) (2.19)
Building wheels for collected packages: pycookiecheat
Building wheel for pycookiecheat (setup.py) ... done
Stored in directory: /tmp/pip-ephem-wheel-cache-m3pfsn3n/wheels/ee/b4/70/b0c41074a262957218b1c878a034bc43292d3c8d5dbb121ca0
Successfully built pycookiecheat
###########################################################################

from pycookiecheat import chrome_cookies
import requests
url='https://learning.oreilly.com/home/'
cookies = chrome_cookies(url)
Traceback (most recent call last):
File "", line 1, in
File "/home/msingh/anaconda3/lib/python3.7/site-packages/pycookiecheat/pycookiecheat.py", line 228, in chrome_cookies
init_vector=config['init_vector'])
File "/home/msingh/anaconda3/lib/python3.7/site-packages/pycookiecheat/pycookiecheat.py", line 63, in chrome_decrypt
return clean(decrypted)
File "/home/msingh/anaconda3/lib/python3.7/site-packages/pycookiecheat/pycookiecheat.py", line 40, in clean
return decrypted[:-last].decode('utf8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc0 in position 0: invalid start byte

Empty response

  • Operating system and version: Debian 4.19.118-2+deb10u1 (2020-06-07) x86_64 GNU/Linux
  • Python version: Python 3.7.6
  • pycookiecheat version: Dev branch

My Issue

I'm not sure if I'm doing something wrong or if there is an issue.
first, it says that by default it takes chromium cookies, which is what I want. However I'm getting this error:

Unable to connect to cookie_file at: /home/username/.config/google-chrome/Default/Cookies

Changing to the correct folder with that command:

cookies = chrome_cookies(url,cookie_file="/home/username/.config/chromium/Default/Cookies")

Printing the cookies variable gives me all the correct keys, but all values are empty.

Instead of that, trying to force the browser with this:

cookies = chrome_cookies(url, browser="Chromium")

Returns the same empty list. Here is the full output:

>>> from pycookiecheat import chrome_cookies
>>> url = 'https://domain.com/lel/fr/mes-groupes'
>>> cookies = chrome_cookies(url, browser="Chromium")
>>> print(cookies)
{'registration_origin': '', 'autoexclusion': '', 'pausedejeu': '', '__utma': '', '__utmc': '', '__utmz': '', '_ga': '', '_gid': '', 'AB_precedent': '', 'AB_vu': '', '__errAttempt': '', '__zlcmid': '', 'domain_auth': '', 'domain_login': '', 'logged_in': '', 'typeTestAB': '', 'iam_session_transferred': '', 'lq-test': '', 'urlRedirection': '', 'catfishAfficher': ''}

Looking into the SQLite database, they are v11 cookies.

I'm able to get my password using secret-tool search application chromium but not sure it helps.

WHYT


Please make sure you've taken these steps before submitting a new issue:

  • Include the Python and pycookiecheat version in your issue
  • Ensure you're running a supported version of Python
  • Run pycookiecheat in debug mode if applicable and include
    relevant output
  • Search the existing (including closed) issues
  • Please use codeblocks for any code, config, program output, etc.

Two-factor authentication

Is there a way to bypass an initial two-factor authentication ("you are logging in from a new browser, send an authentication code to email")? I am logged in on chrome but through python it registers as "new browser". Thank you for developing this by the way, it has made getting past the login page so easy.

I'm just using simple script to download a pdf at url which requires login. But unfortunately this downloads the page after the username & password login telling me that I need to authenticate using a code by either clicking on "Send me an email" or "Send me a text" button (which presumably directs you to a page with an input field for this code). If there is a miraculous way to get through this page it'd be grand but otherwise it seems understandable - I suppose it makes sense considering they use the "are you a robot?" checks sometimes as well.

cookies = chrome_cookies(url)
s = requests.Session()
r = s.get(url, cookies=cookies)
options = {'cookie': s.cookies.items(), 'javascript-delay': 1000}
pdf = pdfkit.from_url(url, "page.pdf", options=options)

Error while using lib

I ran the same code

from pycookiecheat import chrome_cookies
import requests

url = 'http://example.com/fake.html'
cookies = chrome_cookies(url)
r = requests.get(url, cookies=cookies)

and keep getting following error, any idea?

File "/Users/kelvin/anaconda/envs/gl-env/lib/python2.7/site-packages/pycookiecheat/pycookiecheat.py", line 27
def clean(decrypted: bytes) -> str:
^
SyntaxError: invalid syntax

GLib.GError: g-io-error-quark: Cannot autolaunch D-Bus without X11 $DISPLAY (0)

I am getting this error as I am trying to run my flask app on a server running on Ubuntu
Not really sure what the cause is or how to resolve it
Can you help me with this issue?

Traceback (most recent call last):,
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 2292, in wsgi_app,
response = self.full_dispatch_request(),
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1815, in full_dispatch_request,
rv = self.handle_user_exception(e),
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1718, in handle_user_exception,
reraise(exc_type, exc_value, tb), referer:
File "/usr/local/lib/python3.6/dist-packages/flask/_compat.py", line 35, in reraise, referer:
raise value,
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1813, in full_dispatch_request,
rv = self.dispatch_request(),
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1799, in dispatch_request,
return self.view_functionsrule.endpoint,
File "/var/www/FlaskApp/FlaskApp/init.py", line 26, in query_submit,
cookies = chrome_cookies(url),
File "/usr/local/lib/python3.6/dist-packages/pycookiecheat/pycookiecheat.py", line 169, in chrome_cookies,
config = get_linux_config(browser),
File "/usr/local/lib/python3.6/dist-packages/pycookiecheat/pycookiecheat.py", line 128, in get_linux_config,
service = Secret.Service.get_sync(flags),
GLib.GError: g-io-error-quark: Cannot autolaunch D-Bus without X11 $DISPLAY (0)

GLib.Error: g-io-error-quark problem

Dear guys!

I've got a problem on using pycookiecheat in Ubuntu 16.04 LTS, python 2.7 environment. All installation seem to be successful but got a problem when using the pycookiecheat (version 0.3.5). The error message is "GLib.Error: g-io-error-quark: Error calling StartServiceByName for org.freedesktop.secrets: Timeout was reached (24)," so that I've tried to resolve the issue but never have any luck.

Please, give me any clue to resolve it. Thanks for advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.