Issue #21323: Fix http.server to again handle scripts in CGI subdirectories,

broken by the fix for security issue #19435.  Patch by Zach Byrne.
This commit is contained in:
Ned Deily 2014-07-12 22:12:39 -07:00
commit 217f4cd7ee
4 changed files with 25 additions and 5 deletions

View File

@ -994,16 +994,16 @@ class CGIHTTPRequestHandler(SimpleHTTPRequestHandler):
def run_cgi(self): def run_cgi(self):
"""Execute a CGI script.""" """Execute a CGI script."""
dir, rest = self.cgi_info dir, rest = self.cgi_info
path = dir + '/' + rest
i = rest.find('/') i = path.find('/', len(dir)+1)
while i >= 0: while i >= 0:
nextdir = rest[:i] nextdir = path[:i]
nextrest = rest[i+1:] nextrest = path[i+1:]
scriptdir = self.translate_path(nextdir) scriptdir = self.translate_path(nextdir)
if os.path.isdir(scriptdir): if os.path.isdir(scriptdir):
dir, rest = nextdir, nextrest dir, rest = nextdir, nextrest
i = rest.find('/') i = path.find('/', len(dir)+1)
else: else:
break break

View File

@ -324,10 +324,13 @@ class CGIHTTPServerTestCase(BaseTestCase):
self.cwd = os.getcwd() self.cwd = os.getcwd()
self.parent_dir = tempfile.mkdtemp() self.parent_dir = tempfile.mkdtemp()
self.cgi_dir = os.path.join(self.parent_dir, 'cgi-bin') self.cgi_dir = os.path.join(self.parent_dir, 'cgi-bin')
self.cgi_child_dir = os.path.join(self.cgi_dir, 'child-dir')
os.mkdir(self.cgi_dir) os.mkdir(self.cgi_dir)
os.mkdir(self.cgi_child_dir)
self.nocgi_path = None self.nocgi_path = None
self.file1_path = None self.file1_path = None
self.file2_path = None self.file2_path = None
self.file3_path = None
# The shebang line should be pure ASCII: use symlink if possible. # The shebang line should be pure ASCII: use symlink if possible.
# See issue #7668. # See issue #7668.
@ -361,6 +364,11 @@ class CGIHTTPServerTestCase(BaseTestCase):
file2.write(cgi_file2 % self.pythonexe) file2.write(cgi_file2 % self.pythonexe)
os.chmod(self.file2_path, 0o777) os.chmod(self.file2_path, 0o777)
self.file3_path = os.path.join(self.cgi_child_dir, 'file3.py')
with open(self.file3_path, 'w', encoding='utf-8') as file3:
file3.write(cgi_file1 % self.pythonexe)
os.chmod(self.file3_path, 0o777)
os.chdir(self.parent_dir) os.chdir(self.parent_dir)
def tearDown(self): def tearDown(self):
@ -374,6 +382,9 @@ class CGIHTTPServerTestCase(BaseTestCase):
os.remove(self.file1_path) os.remove(self.file1_path)
if self.file2_path: if self.file2_path:
os.remove(self.file2_path) os.remove(self.file2_path)
if self.file3_path:
os.remove(self.file3_path)
os.rmdir(self.cgi_child_dir)
os.rmdir(self.cgi_dir) os.rmdir(self.cgi_dir)
os.rmdir(self.parent_dir) os.rmdir(self.parent_dir)
finally: finally:
@ -469,6 +480,11 @@ class CGIHTTPServerTestCase(BaseTestCase):
self.assertEqual((b'Hello World' + self.linesep, 'text/html', 200), self.assertEqual((b'Hello World' + self.linesep, 'text/html', 200),
(res.read(), res.getheader('Content-type'), res.status)) (res.read(), res.getheader('Content-type'), res.status))
def test_nested_cgi_path_issue21323(self):
res = self.request('/cgi-bin/child-dir/file3.py')
self.assertEqual((b'Hello World' + self.linesep, 'text/html', 200),
(res.read(), res.getheader('Content-type'), res.status))
class SocketlessRequestHandler(SimpleHTTPRequestHandler): class SocketlessRequestHandler(SimpleHTTPRequestHandler):
def __init__(self): def __init__(self):

View File

@ -186,6 +186,7 @@ Alastair Burt
Tarn Weisner Burton Tarn Weisner Burton
Lee Busby Lee Busby
Ralph Butler Ralph Butler
Zach Byrne
Nicolas Cadou Nicolas Cadou
Jp Calderone Jp Calderone
Arnaud Calmettes Arnaud Calmettes

View File

@ -38,6 +38,9 @@ Library
as documented. The pattern and source keyword parameters are left as as documented. The pattern and source keyword parameters are left as
deprecated aliases. deprecated aliases.
- Issue #21323: Fix http.server to again handle scripts in CGI subdirectories,
broken by the fix for security issue #19435. Patch by Zach Byrne.
Tests Tests
----- -----