Tôi hiện đang điều tra một số cơ chế bảo mật liên quan đến pathTraversal và gặp phải một hành vi kỳ lạ của java.io.File.getCanonicalPath(). Tôi nghĩ CanonicalPath sẽ luôn đại diện cho con đường duy nhất thực sự của tập tin trừu tượng nằm bên dưới. Tuy nhiên, nếu tên tập tin bao gồm một trong hai dấu chấm theo sau là một không gian thì CanonicalPath dường như không đại diện cho đường dẫn chính xác nữa.Tệp Java canonicalPath với tailing '..' dẫn đến hành vi không nhất quán
Dưới đây là ví dụ:
File root = new File("c:/git/");
String relative = ".. /.. \\";
File concatFile = new File (root.getCanonicalPath(), relative);
System.out.println("ConcatFileAbsolute: '" + concatFile.getAbsolutePath() + "'");
System.out.println("ConcatFileCanonical: '" + concatFile.getCanonicalPath() + "'");
File canonFile = new File(concatFile.getCanonicalPath());
System.out.println("\ncanonFileCanonical: '" + canonFile.getCanonicalPath() + "'");
System.out.println("canonFileAbsolute: '" + canonFile.getAbsolutePath() + "'");
System.out.println("canonFileName: '" + canonFile.getName() + "'\n");
for (File file : canonFile.listFiles()) {
System.out.println("canon: '" + file.getCanonicalPath() + "' - absolute: '" + file.getAbsolutePath()+ "'");
}
điều khiển Output:
ConcatFileAbsolute: 'C:\git\.. \.. '
ConcatFileCanonical: 'C:\git\.. \'
canonFileCanonical: 'C:\git\'
canonFileAbsolute: 'C:\git\.. '
canonFileName: '.. '
canon: 'C:\git\.. \$Recycle.Bin' - absolute: 'C:\git\.. \$Recycle.Bin'
canon: 'C:\git\.. \.m2' - absolute: 'C:\git\.. \.m2'
canon: 'C:\git\.. \boot' - absolute: 'C:\git\.. \boot'
...other content of C:/
Như bạn có thể thấy mặc dù canonicalPath của canonFile rõ ràng chỉ ra vị trí của nó trong C: \ git \, nhưng danh sách .listFiles tất cả các tệp trong C :.
Điều này chỉ xảy ra nếu tôi sử dụng hàm tạo tệp (String, String) mới. Nếu tôi thay đổi dòng thứ ba thành File concatFile = new File (root.getCanonicalPath() + relative); sau đó đầu ra là như mong đợi:
ConcatFileAbsolute: 'C:\git.. \.. '
ConcatFileCanonical: 'C:\git\'
- The following output then lists files under C:\git\
Tôi không biết liệu hành vi này có giống nhau trên các hệ thống giống như Unix hay không.
Ai đó có thể làm rõ hành vi này? Đây có phải là mục đích không?
Cảm ơn bạn đã trả trước!
Nếu bạn muốn thêm một cái gì đó cho câu hỏi của bạn, chỉnh sửa câu hỏi, mã trong các nhận xét phần lớn là không đọc được. – pvg