FlawOpen

flawopen.com/Path traversal/Python os.path.join()

Apakah os.path.join() Python mencegah path traversal?

CWE-22: Path TraversalHalaman referensi
Jawaban singkat

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.

VULNERABLE
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.
SECURE — resolve and check containment
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.

Pertanyaan umum

Apakah pathlib berperilaku sama?

Ya. Operator / pada Path membuang komponen sebelumnya saat jalur berikutnya absolut. Resolve hasilnya dan pastikan berada di dalam basis yang diizinkan.

Apakah realpath() menghilangkan race?

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.

Referensi

Lihat juga Path traversal (CWE-22): cara kerja dan cara mencegahnya di setiap bahasa — flawopen.com Apa itu kerentanan Zip Slip? Node.js path.join() tidak mencegah Path Traversal PHP include() dan jalur yang dikendalikan pengguna