Skip to content

Commit 74f8769

Browse files
committed
donate-cpu-server: do not serve files outside the result path
1 parent b2d8361 commit 74f8769

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

‎test/tools/donate_cpu_server_test.py‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,32 @@ def test_parse_req():
1515
_test_parse_req("GET /head-uninitvar?pkgs=1 HTTP/1.1", '/head-uninitvar', {'pkgs': '1'})
1616
_test_parse_req("GET /crash.html?pkgs=1 HTTP/1.1", '/crash.html', {'pkgs': '1'})
1717
_test_parse_req("GET /head-uninitvar?pkgs=1&pkgs2=2 HTTP/1.1", '/head-uninitvar', {'pkgs': '1', 'pkgs2': '2'})
18+
19+
class _Connection:
20+
def __init__(self):
21+
self.data = b''
22+
23+
def send(self, data):
24+
self.data += data
25+
return len(data)
26+
27+
def close(self):
28+
pass
29+
30+
def _http_get(result_path, url):
31+
conn = _Connection()
32+
donate_cpu_server.HttpClientThread(conn, 'GET {} HTTP/1.1'.format(url), str(result_path), []).run()
33+
return conn.data.decode('utf-8')
34+
35+
def test_file_outside_result_path(tmp_path):
36+
result_path = tmp_path / 'donated-results'
37+
result_path.mkdir()
38+
(result_path / 'pkg').write_text('result data')
39+
(tmp_path / 'secret.txt').write_text('secret data')
40+
41+
resp = _http_get(result_path, '/pkg')
42+
assert resp.startswith('HTTP/1.1 200 OK') and resp.endswith('result data')
43+
44+
resp = _http_get(result_path, '/../secret.txt')
45+
assert resp.startswith('HTTP/1.1 404 Not Found')
46+
assert 'secret data' not in resp

‎tools/donate-cpu-server.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,8 +1275,9 @@ def run(self):
12751275
text = clientsReport(self.resultPath)
12761276
httpGetResponse(self.connection, text, 'text/html')
12771277
else:
1278-
filename = self.resultPath + url
1279-
if not os.path.isfile(filename):
1278+
result_path = os.path.normpath(self.resultPath)
1279+
filename = os.path.normpath(result_path + url)
1280+
if os.path.commonpath([result_path, filename]) != result_path or not os.path.isfile(filename):
12801281
print_ts('HTTP/1.1 404 Not Found')
12811282
self.connection.send(b'HTTP/1.1 404 Not Found\r\n\r\n')
12821283
else:

0 commit comments

Comments
 (0)