Skip to content

Conversation

@hamzaavvan
Copy link

@hamzaavvanhamzaavvan commented Mar 13, 2021

Due to no protection against multiple (/) at the beginning of a url an attacker could achieve an open redirection by crafting a malformed URI followed by an existing directory.

Payload: http://127.0.0.1:8000//attacker.com/..%2f..%2f../anyexistingdirectory

The main reason behind open redirection is that there's no (/) at the end of anyexistingdirectory because the server is checking for the path supplied is a valid directory at send_head() method from Lib/http/server.py. Right after that, it's checking for the path ending with a (/) or not. So, if there's no (/) at the end of the path then the server will issue a Location header to redirect the web client to that specific directory.

While issuing the redirection, this part //attacker.com/..%2f..%2f../anyexistingdirectory will be sent to the Location header's value due to which any web client or browser will consider it as a new url because of multiple (/) at the beginning of the path.

So to mitigate this issue I decided to use regex to replace all the occurrences of (/) from the beginning of the path.

self.path=re.sub(r'(^(/|\\)+)', '/', self.path)

This regex will replace multiple entries (if present) of (/) or (\) from the beginning of the path. So that the path would be:

  1. //attacker.com/..%2f..%2f../anyexistingdirectory -> /attacker.com/..%2f..%2f../anyexistingdirectory
  2. //\attacker.com/..%2f..%2f../anyexistingdirectory -> /attacker.com/..%2f..%2f../anyexistingdirectory
  3. \//\attacker.com/..%2f..%2f../anyexistingdirectory -> /attacker.com/..%2f..%2f../anyexistingdirectory

And according to these test cases there was no redirection issued from the server after implementing the fix.

https://bugs.python.org/issue43223

@hamzaavvanhamzaavvan changed the title bpo-43223: Patched Open Redirection In SimpleHTTPServer Modulebpo-43223: [SECURITY] Patched Open Redirection In SimpleHTTPServer ModuleMar 13, 2021
@hamzaavvanhamzaavvanforce-pushed the fix-issue-43223 branch 2 times, most recently from e2137b6 to 403490cCompareMarch 16, 2021 17:42
@hamzaavvanhamzaavvanforce-pushed the fix-issue-43223 branch 3 times, most recently from f61138a to 0fe6eedCompareMarch 16, 2021 18:09
Copy link
Member

@vstinnervstinner left a comment

Choose a reason for hiding this comment

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

Can you please try to write an unit test?

@github-actions
Copy link

This PR is stale because it has been open for 30 days with no activity.

@github-actionsgithub-actionsbot added the stale Stale PR or inactive for long period of time. label Apr 18, 2021
@hamzaavvan
Copy link
Author

Sorry I was busy with my other projects.
Will be pushing the test case shortly.

@hamzaavvan
Copy link
Author

Since I'm new to writing test cases, please help me in correcting the code if something went wrong.

@github-actionsgithub-actionsbot removed the stale Stale PR or inactive for long period of time. label May 7, 2021
Fix an open redirection vulnerability in the HTTP server when a URL contains ``//``. Added test case for bpo-43223 patch
@ned-deilyned-deily removed their request for review May 21, 2021 22:03
@hamzaavvan
Copy link
Author

@vstinner please have a look at the unit test.


def test_http_parse_request(self):
self.assertEqual(re.sub(r'^/+', '/', '//test.com'), '/test.com', '//test.com should be converted to a proper relative path')
self.assertEqual(re.sub(r'^/+', '/', '///test.com'), '/test.com', '///test.com should be converted to a proper relative path')
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't test anything useful. It only checks that some regular expression matches two strings. Since your code change is in http.server, your test should execute the http.server path that you changed.

A good test should fail without your code change to http.server, and pass with your change.

Copy link
Author

@hamzaavvanhamzaavvanAug 21, 2021

Choose a reason for hiding this comment

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

Sorry I've been away due to my workload. But now as I've got some spare time I can do it better. As I've already said earlier that I'm new to writing these test cases and after checking out your comment I'm still confused about your requirements

Can you please elaborate these two statements:

Since your code change is in http.server, your test should execute the http.server path that you changed.

and this one:

A good test should fail without your code change to http.server, and pass with your change.

Copy link
Contributor

Choose a reason for hiding this comment

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

@hamzaavvan, to put it in the simplest terms:

  • on a clean checkout of the main branch, write a test that fails because it triggers the problem described in BPO-43223; this will prove we have a problem;
  • then include your fix to prove that the fix solved the problem.

The test will have to actually run the HTTP server to be useful.

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@jhadvig
Copy link

@hamzaavvan ping :)

@hamzaavvan
Copy link
Author

hamzaavvan commented Apr 8, 2022 via email

@gpshead
Copy link
Member

This PR has been replaced by #93879

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@hamzaavvan@bedevere-bot@jhadvig@gpshead@ambv@vstinner@ned-deily@the-knights-who-say-ni