Skip to content

Commit

Permalink
Raise ValueError if method contains control characters (#1800)
Browse files Browse the repository at this point in the history
  • Loading branch information
sethmlarson committed Feb 17, 2020
1 parent a46c08c commit 1dd69c5
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changes
=======

master (dev)
------------

* Raise ``ValueError`` if control characters are given in
the ``method`` parameter of ``HTTPConnection.request()`` (Pull #1800)


1.25.8 (2020-01-20)
-------------------

Expand Down
14 changes: 14 additions & 0 deletions src/urllib3/connection.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from __future__ import absolute_import
import re
import datetime
import logging
import os
Expand Down Expand Up @@ -58,6 +59,8 @@ class ConnectionError(Exception):
# (ie test_recent_date is failing) update it to ~6 months before the current date.
RECENT_DATE = datetime.date(2019, 1, 1)

_CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]")


class DummyConnection(object):
"""Used to detect a failed ConnectionCls import."""
Expand Down Expand Up @@ -184,6 +187,17 @@ def connect(self):
conn = self._new_conn()
self._prepare_conn(conn)

def putrequest(self, method, url, *args, **kwargs):
"""Send a request to the server"""
match = _CONTAINS_CONTROL_CHAR_RE.search(method)
if match:
raise ValueError(
"Method cannot contain non-token characters %r (found at least %r)"
% (method, match.group())
)

return _HTTPConnection.putrequest(self, method, url, *args, **kwargs)

def request_chunked(self, method, url, body=None, headers=None):
"""
Alternative to the common request method, which sends the
Expand Down
6 changes: 6 additions & 0 deletions test/with_dummyserver/test_connectionpool.py
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,12 @@ def test_dns_error(self):
with pytest.raises(MaxRetryError):
pool.request("GET", "/test", retries=2)

@pytest.mark.parametrize("char", [" ", "\r", "\n", "\x00"])
def test_invalid_method_not_allowed(self, char):
with pytest.raises(ValueError):
with HTTPConnectionPool(self.host, self.port) as pool:
pool.request("GET" + char, "/")

def test_percent_encode_invalid_target_chars(self):
with HTTPConnectionPool(self.host, self.port) as pool:
r = pool.request("GET", "/echo_params?q=\r&k=\n \n")
Expand Down

0 comments on commit 1dd69c5

Please sign in to comment.