flawopen.com/Path traversal/Python os.path.join()
Apakah os.path.join() Python mencegah path traversal?
Tidak. Bayangkan direktori dasar sebagai ruangan: .. melewati ruangan induk; jalur absolut adalah alamat baru yang membuat os.path.join() membuang ruangan awal. Resolve jalur akhir dan pastikan tetap di direktori yang diizinkan sebelum membuka file.
import os base_dir = "/srv/uploads" user_filename = "../../outside/demo.txt" path = os.path.join(base_dir, user_filename) # Relative traversal can leave the base. path = os.path.join(base_dir, "/outside/demo.txt") # An absolute segment discards base_dir.
import os
def resolve_under_base(base_dir, user_filename):
if not isinstance(user_filename, str) or not user_filename:
raise ValueError("Invalid filename")
base = os.path.realpath(base_dir)
candidate = os.path.realpath(
os.path.join(base, user_filename)
)
try:
inside = os.path.commonpath((base, candidate)) == base
except ValueError: # e.g. different Windows drives
inside = False
if not inside or candidate == base:
raise ValueError("Invalid filename")
return candidate
Dua perilaku penggabungan jalur
Komponen .. dapat membawa jalur relatif keluar direktori tujuan. Dokumentasi Python menyebut komponen absolut membuat os.path.join() membuang komponen sebelumnya; aturan drive dan root Windows berbeda dari POSIX. pathlib.Path(base) / user_input juga demikian. Penggabungan dan normalisasi bukan pemeriksaan otorisasi.
Mengapa commonpath() lebih aman daripada prefiks teks
Resolve basis tepercaya dan kandidat sebelum membandingkan. os.path.commonpath() membandingkan komponen jalur, bukan prefiks karakter, dan memunculkan ValueError untuk root atau drive yang tidak cocok; tolak kasus itu. realpath() resolve symlink saat pemeriksaan, tetapi tidak mencegah perubahan sebelum file dibuka. Jika pihak lain dapat mengubah pohon, gunakan akses descriptor dan kontrol no-follow yang sesuai.
- ✓Tolak masukan kosong dan masukan yang bukan string.
- ✓Resolve basis dan kandidat; wajibkan
commonpath((base, candidate)) == base. TolakValueErrordan direktori dasar itu sendiri jika yang diminta file. - ✓Pisahkan pemeriksaan batas jalur dari otorisasi; izinkan hanya file dan operasi yang dibutuhkan endpoint.
- ✓Jika pengguna tak tepercaya dapat mengubah symlink, cegah race pemeriksaan/penggunaan dengan API descriptor yang sesuai platform.
Pertanyaan umum
Ya. Operator / pada Path membuang komponen sebelumnya saat jalur berikutnya absolut. Resolve hasilnya dan pastikan berada di dalam basis yang diizinkan.
Tidak. Fungsi itu resolve symlink saat validasi; proses lain dapat mengubahnya sebelum file dibuka. Batasi akses tulis atau gunakan operasi relatif-descriptor no-follow bila tersedia.