psf / psf/requests

For Morsel cookies requests expects wrong Expires time format

Open
#6,004 9 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
54.3k
Forks
10.4k
Avg merge
16h 43m
Merged PRs (30d)
3

Description

I'm not sure about this, but it looks that requests is expecting invalid date format in Expires section in Cookies passed as Morsel objects.

morsel_to_cookie (from requests/cookie.py) function parse expires attr if there is no max-age (which is OK) using format from time_template. However this format is set as '%a, %d-%b-%Y %H:%M:%S GMT' which is none of allowed expires section date value described in RFC (https://www.rfc-editor.org/rfc/rfc6265#section-4.1.1).

The nearest format is the first choice from https://www.rfc-editor.org/rfc/rfc2616#section-3.3.1. The difference is that between date parts there should be a space, but requests expects dash.

See Reproduction Steps for very simple example which bases on Python std libs only and crashes.

Expected Result

It's expected that requests properly accepts Morsel cookies when expires follows RFC https://www.rfc-editor.org/rfc/rfc2616#section-3.3.1.

Actual Result

There is ValueError raised by strptime that passed value does not match format.
Example:
ValueError: time data 'Thu, 01 Jan 1970 00:00:00 GMT' does not match format '%a, %d-%b-%Y %H:%M:%S GMT'

Reproduction Steps

    from http.cookies import SimpleCookie
    from requests.cookies import RequestsCookieJar
    cookies = SimpleCookie()
    cookies.load('auth_session=null; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; httponly; samesite=strict')

    jar = RequestsCookieJar()
    jar.update(cookies)

Example above is a simplified case of using async_asgi_testclient to test application written with Starlette with SessionMiddleware. The async_asgi_testclient collects cookies using SimpleCookie class from standard http lib and then pass them to requests lib which is used to perform client test requests.

But this issue is not related to these packages as I reproduced it using only Python standard http lib and requests as above.

System Information

$ python -m requests.help
{
  "chardet": {
    "version": "4.0.0"
  },
  "charset_normalizer": {
    "version": "2.0.9"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "3.3"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.9.9"
  },
  "platform": {
    "release": "5.15.0-1-amd64",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.26.0"
  },
  "system_ssl": {
    "version": "101010cf"
  },
  "urllib3": {
    "version": "1.26.7"
  },
  "using_charset_normalizer": false,
  "using_pyopenssl": false
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Inspect requests/cookie.py, especially morsel_to_cookie and its time_template format. Reproduce the failure with the provided SimpleCookie and RequestsCookieJar example; done means Morsel cookies using the RFC-described space-separated Expires format are accepted without ValueError.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.