python / python/cpython

Windows path traversal in http.server SimpleHTTPRequestHandler.translate_path() via trailing dot/space components

Đang mở
#157,504 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

stdlib type-bug
Ngôn ngữ chính
Python
Star
77.2k
Fork
35.9k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

Bug report

Bug description:

Opening this issue publicly per the request of the Python Security team as the http.server module doesn't implement security guarantees and is not meant for production.

Summary

On Windows, translate_path() filters out only the exact . and .. path components before joining the request path to the served directory. Components such as .. (trailing space) or .. . are not equal to .., so they survive the filter and are appended to the filesystem path. Because Windows strips trailing spaces and dots from each path component during filesystem resolution, a request like GET /..%20/secret.txt resolves to the parent of the document root at file-open time, allowing a remote client to read files outside the configured directory.

Details

Lib/http/server.py, SimpleHTTPRequestHandler.translate_path() (also reached by CGIHTTPRequestHandler on the branches where it still exists).

The per-component filter in translate_path():

path = posixpath.normpath(path)
words = path.split('/')
words = filter(None, words)
path = self.directory
for word in words:
if os.path.dirname(word) or word in (os.curdir, os.pardir):
# Ignore components that are not a simple file/directory name
continue
path = os.path.join(path, word)

os.path.dirname('.. ') is empty and '.. ' in (os.curdir, os.pardir) is False, so .. is treated as an ordinary filename and joined onto the path. send_head() then uses the result directly:

path = self.translate_path(self.path)
...
f = open(path, 'rb')

There is no canonicalization or containment check between translate_path() and the open().

I verified the code-path bypass locally on Linux by reproducing the exact translate_path() logic against both posixpath and ntpath. /..%20/secret.txt and /..%20./secret.txt both survive the filter and produce a component .. / .. . appended after the served directory, while a plain /../secret.txt is correctly collapsed by normpath and rejected. The escape itself relies on documented Windows path canonicalization (trailing spaces and dots stripped per component). I did not run this against a live Windows.

The POSIX runtime is not affected: there .. is a literal directory name (dot dot space) that does not exist, so the request returns 404 and never escapes the served directory.

The vulnerable filter is byte-identical on every currently supported branch: main, 3.15, 3.14, 3.13, 3.12, 3.11 and 3.10. 3.9 and earlier are EOL. CGIHTTPRequestHandler, which reaches the same code, was removed on main in https://github.com/python/cpython/issues/133810 and is deprecated-since-3.13 / removed-in-3.15, but is still present in the maintenance branches.

Disclosure

This issue was found by AISLE in partnership with Red Hat.

CPython versions tested on:

CPython main branch, 3.16, 3.15, 3.14, 3.13, 3.12, 3.11, 3.10

Operating systems tested on:

Windows

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu trong Lib/http/server.py tại SimpleHTTPRequestHandler.translate_path(), sau đó lần theo send_head() và đường dẫn CGIHTTPRequestHandler trên các nhánh maintenance. Tái hiện các request có dấu chấm/khoảng trắng ở cuối trên Windows và kiểm tra các test http.server hiện có để tìm phạm vi bao phủ phù hợp. Hoàn tất khi các request không thể phân giải ra ngoài thư mục được phục vụ, trong khi các đường dẫn thông thường vẫn tiếp tục hoạt động trên các nhánh bị ảnh hưởng.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
python
Lĩnh vực
backend, security
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
48/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.