@@ -150,6 +150,10 @@
|
150 | 150 | # _is_allowed_url_pchars_re = re.compile(r"^[/!$&'()*+,;=:@%a-zA-Z0-9._~-]+$") |
151 | 151 | # We are more lenient for assumed real world compatibility purposes. |
152 | 152 | |
| 153 | +# These characters are not allowed within HTTP method names |
| 154 | +# to prevent http header injection. |
| 155 | +_contains_disallowed_method_pchar_re = re.compile('[\x00-\x1f]') |
| 156 | + |
153 | 157 | # We always set the Content-Length header for these methods because some |
154 | 158 | # servers will otherwise respond with a 411 |
155 | 159 | _METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'} |
@@ -1109,6 +1113,8 @@ def putrequest(self, method, url, skip_host=False,
|
1109 | 1113 | else: |
1110 | 1114 | raise CannotSendRequest(self.__state) |
1111 | 1115 | |
| 1116 | +self._validate_method(method) |
| 1117 | + |
1112 | 1118 | # Save the method for use later in the response phase |
1113 | 1119 | self._method = method |
1114 | 1120 | |
@@ -1199,6 +1205,15 @@ def _encode_request(self, request):
|
1199 | 1205 | # ASCII also helps prevent CVE-2019-9740. |
1200 | 1206 | return request.encode('ascii') |
1201 | 1207 | |
| 1208 | +def _validate_method(self, method): |
| 1209 | +"""Validate a method name for putrequest.""" |
| 1210 | +# prevent http header injection |
| 1211 | +match = _contains_disallowed_method_pchar_re.search(method) |
| 1212 | +if match: |
| 1213 | +raise ValueError( |
| 1214 | +f"method can't contain control characters. {method!r} " |
| 1215 | +f"(found at least {match.group()!r})") |
| 1216 | + |
1202 | 1217 | def _validate_path(self, url): |
1203 | 1218 | """Validate a url for putrequest.""" |
1204 | 1219 | # Prevent CVE-2019-9740. |
|