현재 일부 pathTraversal 관련 보안 메커니즘에서 조사 중이며 java.io.File.getCanonicalPath()의 이상한 동작이 나타납니다. CanonicalPath는 항상 추상적 인 기본 파일의 진정한 고유 한 경로를 나타낼 것이라고 생각했습니다. 그러나 파일 이름에 두 개의 점과 공백이있는 경우 CanonicalPath는 올바른 경로를 더 이상 나타내지 않습니다. 여기 tailing '..'이있는 Java 파일 canonicalPath가 일관성없는 동작으로 이어짐
은 예입니다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()+ "'");
}
콘솔 출력 :
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:/
canonFile의 canonicalPath이 명확하게 C에서의 위치를 나타냅니다 비록 당신이 볼 수 있듯이 : \의 자식 \하지만 .listFiles 목록 C :의 모든 파일.
새 File (String, String) 생성자를 사용하는 경우에만 발생합니다. 3 번째 줄을 File concatFile = new File (root.getCanonicalPath() + relative)로 변경하면; 출력은 예상대로입니다 :
ConcatFileAbsolute: 'C:\git.. \.. '
ConcatFileCanonical: 'C:\git\'
- The following output then lists files under C:\git\
이 동작이 유닉스 계열 시스템에서 유사한 지 모르겠습니다.
누군가가이 동작을 명확히 할 수 있습니까? 이것은 의도 된 것입니까?
감사합니다.
당신이 당신의 질문에 무언가를 추가 질문을 편집 할 경우, 코드 :
그것은 정확히 같은 결과를 제공합니다 내가 승리 API를 테스트하기 위해 간단한 VBS 코드를 작성했습니다를 테스트하려면 코멘트에서 크게 읽을 수 없습니다. – pvg