diff options
author | Andrew M. Kuchling <amk@amk.ca> | 2006-05-31 14:08:48 (GMT) |
---|---|---|
committer | Andrew M. Kuchling <amk@amk.ca> | 2006-05-31 14:08:48 (GMT) |
commit | 622f14417521bcc94d39f6da638ee539c2cbaeb7 (patch) | |
tree | 103f3e45d7e7c49e7fa8ebdc1c00c3df7dad4151 /Lib/SimpleXMLRPCServer.py | |
parent | bc09e1086e971d0dd4b846064832d23855eb0cd6 (diff) | |
download | cpython-622f14417521bcc94d39f6da638ee539c2cbaeb7.zip cpython-622f14417521bcc94d39f6da638ee539c2cbaeb7.tar.gz cpython-622f14417521bcc94d39f6da638ee539c2cbaeb7.tar.bz2 |
[Bug #1473048]
SimpleXMLRPCServer and DocXMLRPCServer don't look at
the path of the HTTP request at all; you can POST or
GET from / or /RPC2 or /blahblahblah with the same results.
Security scanners that look for /cgi-bin/phf will therefore report
lots of vulnerabilities.
Fix: add a .rpc_paths attribute to the SimpleXMLRPCServer class,
and report a 404 error if the path isn't on the allowed list.
Possibly-controversial aspect of this change: the default makes only
'/' and '/RPC2' legal. Maybe this will break people's applications
(though I doubt it). We could just set the default to an empty tuple,
which would exactly match the current behaviour.
Diffstat (limited to 'Lib/SimpleXMLRPCServer.py')
-rw-r--r-- | Lib/SimpleXMLRPCServer.py | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/Lib/SimpleXMLRPCServer.py b/Lib/SimpleXMLRPCServer.py index db7749a..c7646cf 100644 --- a/Lib/SimpleXMLRPCServer.py +++ b/Lib/SimpleXMLRPCServer.py @@ -423,6 +423,17 @@ class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): XML-RPC requests. """ + # Class attribute listing the accessible path components; + # paths not on this list will result in a 404 error. + rpc_paths = ('/', '/RPC2') + + def is_rpc_path_valid(self): + if self.rpc_paths: + return self.path in self.rpc_paths + else: + # If .rpc_paths is empty, just assume all paths are legal + return True + def do_POST(self): """Handles the HTTP POST request. @@ -430,6 +441,11 @@ class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): which are forwarded to the server's _dispatch method for handling. """ + # Check that the path is legal + if not self.is_rpc_path_valid(): + self.report_404() + return + try: # Get arguments by reading body of request. # We read this in chunks to avoid straining @@ -468,6 +484,18 @@ class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): self.wfile.flush() self.connection.shutdown(1) + def report_404 (self): + # Report a 404 error + self.send_response(404) + response = 'No such page' + self.send_header("Content-type", "text/plain") + self.send_header("Content-length", str(len(response))) + self.end_headers() + self.wfile.write(response) + # shut down the connection + self.wfile.flush() + self.connection.shutdown(1) + def log_request(self, code='-', size='-'): """Selectively log an accepted request.""" |