2016-12-22 1 views
6

현재 일부 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\ 

이 동작이 유닉스 계열 시스템에서 유사한 지 모르겠습니다.

누군가가이 동작을 명확히 할 수 있습니까? 이것은 의도 된 것입니까?

감사합니다.

+0

당신이 당신의 질문에 무언가를 추가 질문을 편집 할 경우, 코드 :

Dim folderName folderName = "c:\temp\.. " Dim fso Set fso = CreateObject("Scripting.FileSystemObject") Dim fullpath fullpath = fso.GetAbsolutePathName(folderName) WScript.Echo "fullpath: " & fullpath 

그것은 정확히 같은 결과를 제공합니다 내가 승리 API를 테스트하기 위해 간단한 VBS 코드를 작성했습니다를 테스트하려면 코멘트에서 크게 읽을 수 없습니다. – pvg

답변

3

축하해주세요! WinAPI의 가능한 버그 (또는 기능?)를 발견했습니다.

은보다 구체적으로, 귀하의 질문은 한 줄의 코드로 줄일 수있다 :

이유는 무엇입니까 new File("c:\\temp\\.. ").getCanonicalPath() 반환 c:\temp\ 대신 c:\?

짧은 대답 : 꼬리 공간 때문에 .. 이후 (예, 위에서 언급 했음).

긴 대답 : 우리는 기본이되는 클래스의 자바 구현 내부 보면됩니다, 우리는 Windows 용은, WinNTFileSystem 클래스 것으로 나타났습니다 곳이 깨진 값을 반환 canonicalize0("c:\\temp\\.. ")기본 방법. 왜?

fullpath: C:\temp 
+0

그 전화에 어떤 종류의 오류보고가 있습니까? '..'는 파일 이름처럼 보입니다. API는 단지 파일 이름을 유효하지 않은 것으로 던지기로 결정했을 것입니다. 어느 쪽이든'c : \ '를 반환하지 않는 것은 완전히 비합리적인 것처럼 보이지 않습니다. – pvg

+0

대단히 감사합니다. 이것은 적어도 OS 레벨에 대해 설명합니다! 내가 java.io.File (construtor뿐만 아니라 getCanonicalPath)의 구현을 올려다 보니 당신 말이 맞습니다. 표준화 및 해결의 fs 특정 구현이 문제인 것처럼 보입니다. – guitarlum

관련 문제