câu trả lời của ircmaxell không hoàn toàn chính xác. Tôi đã nhìn thấy giải pháp đó trong một số đoạn trích nhưng nó có lỗi liên quan đến đầu ra của realpath()
. Chức năng realpath()
loại bỏ các dấu phân cách thư mục dấu, vì vậy hình dung hai thư mục tiếp giáp như:
/foo/bar/baz/
/foo/bar/baz_baz/
Như realpath()
sẽ loại bỏ các phân cách thư mục cuối cùng, phương pháp của bạn sẽ quay trở lại "con đường tốt" nếu $_GET['path']
là bằng" ../ Baz_baz" vì nó sẽ là một cái gì đó giống như
strpos("/foo/bar/baz_baz", "/foo/bar/baz")
Có thể:
$basepath = '/foo/bar/baz/';
$realBase = realpath($basepath);
$userpath = $basepath . $_GET['path'];
$realUserPath = realpath($userpath);
if ($realUserPath === false || strcmp($realUserPath, $realBase) !== 0 || strpos($realUserPath, $realBase . DIRECTORY_SEPARATOR) !== 0) {
//Directory Traversal!
} else {
//Good path!
}
Nguồn
2012-11-25 14:47:12
MainMa hiểu những gì tôi đang cố gắng đạt được. – Johnny
Anh ấy trả về '$ _GET', rõ ràng anh ta đang cố gắng ngăn chặn một cuộc tấn công tra tấn từ thư mục, vì vậy xin đừng nói" bạn chỉ nên làm cho php hoạt động bình thường ngay từ đầu ". – FluorescentGreen5