psf / requests

A simple, yet elegant, HTTP library.
https://requests.readthedocs.io/en/latest/
Apache License 2.0
52.19k stars 9.33k forks source link

Multiple path separators causes bad requests #6784

Open martin-pil opened 3 months ago

martin-pil commented 3 months ago

I'm assuming that change in https://github.com/psf/requests/pull/6644 is the cause of this changed behavior that operations with // in path fails. It seems to be related to Authentication as it is the only thing I could find that does not get trimmed by the change in 6644.

Expected Result

Similar behavior as before 2.32.0

Actual Result

Request captured by wireshark, note that this is the second request as the first got a 401

Hypertext Transfer Protocol POST /axis-cgi/capturemode.cgi HTTP/1.1\r\n Host: 192.168.0.1\r\n User-Agent: python-requests/2.32.3\r\n Accept-Encoding: gzip, deflate, zstd\r\n Accept: /\r\n Connection: keep-alive\r\n Content-Length: 50\r\n [truncated]Authorization: Digest username="root", realm="AXIS_B8A44F45D62F", nonce="UKH3vekeBgA=2b0d57c2d8b8eb15307576e30309cb7b23a2304c", uri="//axis-cgi/capturemode.cgi", response="0a51943f746a0d88c6574f662b457a9c", algorithm="MD5", qo username="root" realm="AXIS_B8A44F45D62F" nonce="UKH3vekeBgA=2b0d57c2d8b8eb15307576e30309cb7b23a2304c" uri="//axis-cgi/capturemode.cgi" response="0a51943f746a0d88c6574f662b457a9c" algorithm="MD5" qop="auth" nc=00000001 \r\n [Full request URI: http://172.26.21.128/axis-cgi/capturemode.cgi] [HTTP request 2/2] [Prev request in frame: 10] [Response in frame: 19] File Data: 50 bytes Data (50 bytes)

Response: Hypertext Transfer Protocol HTTP/1.1 400 Bad Request\r\n Date: Mon, 05 Aug 2024 06:25:23 GMT\r\n Server: Apache/2.4.58 (Unix) OpenSSL/3.0.13\r\n X-Content-Type-Options: nosniff\r\n X-Frame-Options: SAMEORIGIN\r\n X-XSS-Protection: 1; mode=block\r\n [truncated]Content-Security-Policy: default-src 'self'; frame-ancestors 'self'; connect-src 'self' https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com https://*.axis.com mediastream: blob:; script Content-Length: 226\r\n Connection: close\r\n Content-Type: text/html; charset=iso-8859-1\r\n \r\n [HTTP response 2/2] [Time since request: 0.001411000 seconds] [Prev request in frame: 10] [Prev response in frame: 13] [Request in frame: 16] [Request URI: http://192.168.0.1/axis-cgi/capturemode.cgi] File Data: 226 bytes

Reproduction Steps

This was run at a axis camera

import requests

url = "http://192.168.01//axis-cgi/capturemode.cgi"
body = {
            "apiVersion": "1.0",
            "method": "getCaptureModes"}

auth = requests.auth.HTTPDigestAuth("root", "pass")
response = requests.post(url=url, data=json.dumps(body),
                                              auth=auth, proxies=dict(http=None, https=None))

System Information

$ python -m requests.help
{
  "chardet": {
    "version": null
  },
  "charset_normalizer": {
    "version": "3.3.2"
  },
  "cryptography": {
    "version": "42.0.8"
  },
  "idna": {
    "version": "3.7"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.11.2"
  },
  "platform": {
    "release": "6.1.0-21-amd64",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "30200020",
    "version": "24.1.0"
  },
  "requests": {
    "version": "2.32.3"
  },
  "system_ssl": {
    "version": "300000b0"
  },
  "urllib3": {
    "version": "2.2.2"
  },
  "using_charset_normalizer": true,
  "using_pyopenssl": true
}