2009-04-29 3 views
2

나는 내가 신뢰할 수있는 rootPath이고 그렇지 않다면 relativePath입니다. 나는 그 결과가 rootPath 아래인지 확신 할 수있는 방법으로 그들을 결합하기를 원하며 사용자는 ..을 사용하여 시작 지점을 지나갈 수 없다. 당신이 할 수있는 worldPath.Combine의 안전한 버전

답변

5

System.IO.Path.GetFullPath?

확장하려면 : Path.Combine을 사용하고 결과에서 GetFullPath를 호출하고 그 결과가 rootPath로 시작하는지 확인하십시오.

하드 링크로부터 사용자를 보호하지는 않지만 이중 점과 같은 간단한 것을 잡아야합니다.

코드와 위 :

string Resolve(string fileName) 
{ 
    string root = FileRoot(); 
    string ret = Path.GetFullPath(Path.Combine(root, fileName)); 
    if (ret.StartsWith(root.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar)) return ret; 
    throw new ArgumentException("path resolved to out of accesable directroy"); 
} 
+0

유지하기 위해 필요로 끝낼 생각 한 과학적 \ 누가 \ \ 간다 : \ 루트 \로 끝나지 않는 경우에, 그러나 D – BCS

+3

을, 그건 여전히 제한된 트릭을 재생할 수 있습니다. 다른 디렉토리에서 끝나면, 루트 디렉토리의 형제가됩니다.이 디렉토리는 접두어로 시작합니다. 예를 들어 루트는 \ zip \ zop, 상대 경로 .. \ zopper \ zup 일 수 있습니다. \ zip \ zop \ zup에 있지만 \ StartupWith 테스트를 여전히 만족하는 트리 외부에서는 \ zip \ zopper \ zup으로 끝납니다. 위험은 작지만 0은 아닙니다. –

+1

멋진 코너 케이스 ... 코드에 추가 할 것입니다. –

-1

한 가지는 백 슬래시 (\)을 두 번 점 (..)의 수를 계산하고, 번호가 있는지 확인하는 것입니다 hello\..\world == : 나는 같이 상대 경로가 일을 허용 할 할 이중 점의 수가 백 슬래시 수보다 작습니다. 폴더 구조의 rootPath 위로 이동하려면 적어도 두 배의 백 슬래시가 필요합니다. 따라서 한 개 이상의 백 슬래시가있는 relativePath을 허용하는 경우 안전해야합니다.

+0

하지만 \ .. \ ..이 \가 – BCS

+0

난 당신이 내가 좋아하는 실행 횟수 – BCS

2

당신은 Path.GetFullPath()를 호출하고 그것은 당신의 rootPath 신뢰로 시작하면 확인할 수 있습니다. 편집증 경향이있는 경우 rootPath이 루팅되어 있는지 확인하십시오.

public Boolean IsPathSafe(String rootPath, String relativePath) 
{ 
    return rootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) && 
    Path.IsPathRooted(rootPath) && 
    Patch.Combine(rootPath, relativePath).GetFullPath().StartsWith(rootPath); 
} 

첫 번째 테스트에 대한 설명은 technophile의 답변에 대한 Alex Martelli의 의견을 참조하십시오.