Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-39603: Prevent header injection in http methods #18485

Merged
merged 5 commits into from
Jul 18, 2020

Conversation

amiremohamadi
Copy link
Contributor

@amiremohamadi amiremohamadi commented Feb 12, 2020

reject control chars in http method in http.client.putrequest to prevent http header injection

https://bugs.python.org/issue39603

Automerge-Triggered-By: @gvanrossum

@codecov
Copy link

codecov bot commented Feb 12, 2020

Codecov Report

Merging #18485 into master will increase coverage by 0.00%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #18485     +/-   ##
=========================================
  Coverage   82.12%   82.12%             
=========================================
  Files        1955     1955             
  Lines      588958   583810   -5148     
  Branches    44428    44449     +21     
=========================================
- Hits       483663   479453   -4210     
+ Misses      95652    94713    -939     
- Partials     9643     9644      +1     
Impacted Files Coverage Δ
Lib/distutils/tests/test_bdist_rpm.py 30.00% <0.00%> (-65.00%) ⬇️
Lib/distutils/command/bdist_rpm.py 7.63% <0.00%> (-56.88%) ⬇️
Lib/test/test_urllib2net.py 76.92% <0.00%> (-13.85%) ⬇️
Lib/test/test_smtpnet.py 78.57% <0.00%> (-7.15%) ⬇️
Lib/ftplib.py 63.85% <0.00%> (-6.06%) ⬇️
Lib/test/test_ftplib.py 87.11% <0.00%> (-4.72%) ⬇️
Tools/scripts/db2pickle.py 17.82% <0.00%> (-3.97%) ⬇️
Tools/scripts/pickle2db.py 16.98% <0.00%> (-3.78%) ⬇️
Lib/test/test_socket.py 71.94% <0.00%> (-3.77%) ⬇️
Lib/test/test_asyncio/test_base_events.py 91.84% <0.00%> (-3.30%) ⬇️
... and 343 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b138dd2...5d9825f. Read the comment docs.

@amiremohamadi
Copy link
Contributor Author

Should I write some tests??!

Copy link
Member

@alex alex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks correct to me, however I'm far from an expert in the http module, so I'd appreciate a second review.

Copy link
Member

@jaraco jaraco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. By providing an _validate method, it enables subclasses an escape hatch to suppress or customize the validation.

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this basically disallows control characters. It still allows spaces, which seems questionable, and non-ASCII bytes, which seems even more questionable (though probably disallowed by the ASCII encoding requirement), as well as ASCII punctuation characters (which I'm not sure would be useful). Could we just match the entire verb against r"\A\w+\Z"? Or are there use cases for having punctuation or spaces in the HTTP verb( method)?

@@ -1086,6 +1090,7 @@ def putrequest(self, method, url, skip_host=False,
raise CannotSendRequest(self.__state)

# Save the method for use later in the response phase
self._validate_method(method)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Placing the validation right behind this comment is somewhat misleading -- the comment explains the assignment, but the validation is not just for the assignment -- its primary use is for the construction of the request variable a few lines nelow (L1099 in this version). I recommend moving this up and placing blank lines around it.

@amiremohamadi
Copy link
Contributor Author

So this basically disallows control characters. It still allows spaces, which seems questionable, and non-ASCII bytes, which seems even more questionable (though probably disallowed by the ASCII encoding requirement), as well as ASCII punctuation characters (which I'm not sure would be useful). Could we just match the entire verb against r"\A\w+\Z"? Or are there use cases for having punctuation or spaces in the HTTP verb( method)?

@gvanrossum Thank you for the review!
I'm not sure but _encode_request method (L1102) encodes the request (including method) to ASCII. So do we need to restrict non-ASCII characters?

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I'm approving this. The security issue is fixed by this, if people want to screw around with weird verbs I guess the server will just reject it.

@miss-islington miss-islington merged commit 8ca8a2e into python:master Jul 18, 2020
@miss-islington
Copy link
Contributor

Sorry, I can't merge this PR. Reason: Base branch was modified. Review and try the merge again..

3 similar comments
@miss-islington
Copy link
Contributor

Sorry, I can't merge this PR. Reason: Base branch was modified. Review and try the merge again..

@miss-islington
Copy link
Contributor

Sorry, I can't merge this PR. Reason: Base branch was modified. Review and try the merge again..

@miss-islington
Copy link
Contributor

Sorry, I can't merge this PR. Reason: Base branch was modified. Review and try the merge again..

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Jul 18, 2020
reject control chars in http method in http.client.putrequest to prevent http header injection
(cherry picked from commit 8ca8a2e)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
@bedevere-bot
Copy link

GH-21537 is a backport of this pull request to the 3.8 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.8 only security fixes label Jul 18, 2020
@bedevere-bot
Copy link

GH-21538 is a backport of this pull request to the 3.7 branch.

@bedevere-bot
Copy link

GH-21539 is a backport of this pull request to the 3.6 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Jul 18, 2020
reject control chars in http method in http.client.putrequest to prevent http header injection
(cherry picked from commit 8ca8a2e)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Jul 18, 2020
reject control chars in http method in http.client.putrequest to prevent http header injection
(cherry picked from commit 8ca8a2e)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
miss-islington added a commit that referenced this pull request Jul 18, 2020
reject control chars in http method in http.client.putrequest to prevent http header injection
(cherry picked from commit 8ca8a2e)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
miss-islington added a commit that referenced this pull request Jul 18, 2020
reject control chars in http method in http.client.putrequest to prevent http header injection
(cherry picked from commit 8ca8a2e)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
ned-deily pushed a commit that referenced this pull request Jul 19, 2020
)

reject control chars in http method in http.client.putrequest to prevent http header injection
(cherry picked from commit 8ca8a2e)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
ned-deily pushed a commit that referenced this pull request Jul 19, 2020
)

reject control chars in http method in http.client.putrequest to prevent http header injection
(cherry picked from commit 8ca8a2e)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
@orsenthil
Copy link
Member

Thank you, everyone - who got involved with review of this patch. The review comments that were mentioned in bpo ticket seems to have been addressed. The changes look good to me.

arun-mani-j pushed a commit to arun-mani-j/cpython that referenced this pull request Jul 21, 2020
reject control chars in http method in http.client.putrequest to prevent http header injection
shihai1991 pushed a commit to shihai1991/cpython that referenced this pull request Aug 4, 2020
reject control chars in http method in http.client.putrequest to prevent http header injection
shihai1991 pushed a commit to shihai1991/cpython that referenced this pull request Aug 20, 2020
reject control chars in http method in http.client.putrequest to prevent http header injection
@vstinner
Copy link
Member

I created a backport to 3.5, can someone please review it? PR #21946.

larryhastings pushed a commit that referenced this pull request Sep 4, 2020
reject control chars in http method in http.client.putrequest to prevent http header injection

(cherry picked from commit 8ca8a2e)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
encukou pushed a commit to encukou/cpython that referenced this pull request Sep 30, 2020
00354 #
Reject control chars in HTTP method in httplib.putrequest to prevent
HTTP header injection

Backported from Python 3.5-3.10 (and adjusted for py2's single-module httplib):
- https://bugs.python.org/issue39603
- python#18485 (3.10)
- python#21946 (3.5)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
xzy3 pushed a commit to xzy3/cpython that referenced this pull request Oct 18, 2020
reject control chars in http method in http.client.putrequest to prevent http header injection
hroncok pushed a commit to fedora-python/cpython that referenced this pull request Apr 19, 2021
00354 #
Reject control chars in HTTP method in httplib.putrequest to prevent
HTTP header injection

Backported from Python 3.5-3.10 (and adjusted for py2's single-module httplib):
- https://bugs.python.org/issue39603
- python#18485 (3.10)
- python#21946 (3.5)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
hroncok pushed a commit to fedora-python/cpython that referenced this pull request May 19, 2021
00354 #
Reject control chars in HTTP method in httplib.putrequest to prevent
HTTP header injection

Backported from Python 3.5-3.10 (and adjusted for py2's single-module httplib):
- https://bugs.python.org/issue39603
- python#18485 (3.10)
- python#21946 (3.5)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
farazs-github pushed a commit to MediaTek-Labs/cpython that referenced this pull request Nov 12, 2021
stratakis pushed a commit to stratakis/cpython that referenced this pull request Jul 18, 2022
00354 #
Reject control chars in HTTP method in httplib.putrequest to prevent
HTTP header injection

Backported from Python 3.5-3.10 (and adjusted for py2's single-module httplib):
- https://bugs.python.org/issue39603
- python#18485 (3.10)
- python#21946 (3.5)

Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants