bpo-43223: [SECURITY] Patched Open Redirection In SimpleHTTPServer Module by hamzaavvan · Pull Request #24848 · python/cpython (original) (raw)

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