4

I am trying to write a small script that will allow me to see information related to the cookies set by my website.

I want to know if it has secure or httpOnly flags set on them. But so far I wasn't able to do it, I only figured out how to get cookie names and values. Here is my current code:

r = requests.post('url', data=data, headers=headers)

for (name, cookie) in r.cookies.items():
    print name, cookie

So far this works fine, but I want to get information related to the cookies, not the value itself. Cookie meta-data if you will.

How can I achieve that?

Rodrigo Sasaki
  • 7,048
  • 4
  • 34
  • 49

2 Answers2

10

You can extract the information from each cookie individually:

import requests

r = requests.post('http://www.about.com')

for cookie in r.cookies:
    print(cookie.__dict__)
    print(cookie.secure)

This is because r.cookies is an instance of RequestsCookieJar which extends from CookieJar (Python 2: cookielib.CookieJar, Python 3: http.cookiejar.CookieJar). A CookieJar has Cookie objects.

References:

Update: I have not found a way to retrieve the httponly value from a Cookie object. In Python 3, you can define a Morsel object via a dictionary, and it considers httponly to be a standard attribute of a cookie (https://docs.python.org/3/library/http.cookies.html), but I couldn't find any reference to httponly in the defining specification RFC2109 (https://www.ietf.org/rfc/rfc2109.txt).

That said, if httponly is in fact a non-standard attribute, then you can use the following to check if a cookie has it: cookie.has_nonstandard_attr('httponly')

HEADLESS_0NE
  • 3,416
  • 4
  • 32
  • 51
  • You can simply `for cookie in r.cookies:` and you also don't need to import the print_function – Padraic Cunningham Jun 08 '16 at 19:42
  • 2
    Ah nice :) but I saw that it doesn't work for `httpOnly`. At least not on 2.7. Is there a way to reach that one? – Rodrigo Sasaki Jun 08 '16 at 19:51
  • @RodrigoSasaki, I'm not entirely sure about this, but it seems `httponly` is not part of the standard attributes expected in a cookie according to RFC2109 (https://www.ietf.org/rfc/rfc2109.txt). You can check if a cookie contains non standard attributes though like so `cookie.has_nonstandard_attr('httponly')`. Though there's contradicting evidence that `httponly` may also be valid (see: https://docs.python.org/3.5/library/http.cookies.html#http.cookies.Morsel). Just can't find a single reference to it in the RFC2109 document. – HEADLESS_0NE Jun 08 '16 at 20:04
  • @HEADLESS_0NE, I see.. I was just curious really, but I can take care of it from now on :) Thank you for your help! – Rodrigo Sasaki Jun 08 '16 at 20:19
3

Under Python 3, I was not able to retrieve the httpOnly flag from the following:

cookie.get_nonstandard_attr('httpOnly')

and

cookie.has_nonstandard_attr('httpOnly')

returned False even if the httpOnly flag was included with the cookie.

This didn't work with any of the variations of httponly, HttpOnly, etc. either.

Using @HEADLESS_0NE's post, I found you can retrieve the flag by looking at the _rest field in cookie.__dict__. If httpOnly is included in the cookie,

cookie.__dict__['_rest']

will return something like this:

{'HttpOnly': None, ...}

Thus, here is a small helper function to check if a cookie has the httpOnly flag.

def has_http_only(cookie):
    extra_args = cookie.__dict__.get('_rest')
    if extra_args:
        for key in extra_args.keys():
            if key.lower() == 'httponly':
                return True

    return False

The secure flag is automatically added to the cookie object and can be retrieved using cookie.secure.

Kyle
  • 685
  • 7
  • 14
  • The `cookie.has_nonstandard_attr` may not have worked originally because it looks like there were some changes to the casing that Python uses for `HttpOnly`. Mixed case is currently correct and was updated a couple of versions ago. https://hg.python.org/cpython/rev/0d8380c493ad – Jason Capriotti Mar 26 '21 at 20:37