C#에서 zip을 확장할 때 주의해야 할 사항

7835 단어 C#ziptech

C#에서 zip을 확장할 때 주의해야 할 사항


그럼 안녕히 계세요.NET Framework 4.5에서 시작하여 외부 라이브러리 없이 zip 파일을 확장할 수 있습니다.
그 전개 기능을 사용할 때, 파일 단위로 전개할 때 주의해야 할 점이 있다.

총결산


ExtractToFile 함수 및 Path콤보 Combine 함수 위험
  • ExtractToDirectory 함수 활용(ExtractToFile 함수 임의로 호출하지 않음)
  • 어떻게든 사용해야 할 때 전체 경로의 일치성을 확인
  • Zip Slip이란


    작성된 zip 파일의 입구에서 파일 경로의 결합을 이용해'지정된 폴더'이외의 파일을 덮어쓰는'Directritrar Basal'(past labasal) 공격을 한다.
    zip 형식 이외에 몇 가지 압축 형식이 있어 같은 현상이 발생할 수 있다(참고 사이트 참조).

    수법


     - folder/a.txt
     - folder/b.jpg
     - c.html
     - ../malicious_file.txt
    
    상기 파일을 저장하는 zip 파일(공격 파일)을 제공했다고 가정한다.
    다음 코드를 사용하여 이 작업을 확장하면 지정된 폴더 외부에 파일이 생성됩니다.
    string currentDirectory = Directory.GetCurrentDirectory();
    using (var zip = ZipFile.OpenRead("malicious.zip"))
    {
        foreach (var entry in zip.Entries)
        {
            string destPath = Path.Combine(currentDirectory, entry.FullName);
            entry.ExtractToFile(destPath, true);    // ファイルを上書きする
        }
    }
    
    현재 디렉터리가 C:/test일 때 다음 파일을 만듭니다.
     - C:/test/folder/a.txt
     - C:/test/folder/b.jpg
     - C:/test/c.html
     - C:/malicious_file.txt
    
    malicious_file.txt는 지정된 폴더 외부에 생성됩니다.
    참고 사이트[1]에서 서버 측의 문제가 언급되었고 클라이언트 측도 발생할 수 있습니다.

    대책


    string currentDirectory = Directory.GetCurrentDirectory();
    using (var zip = ZipFile.OpenRead("malicious.zip"))
    {
        foreach (var entry in zip.Entries)
        {
            // 以下の行を修正
            string destPath = Path.GetFullPath(Path.Combine(currentDirectory, entry.FullName));
            // 以下の4行を追加
            if (!destPath.StartsWith(currentDirectory))
            {
                throw new Exception("Malicious entry has detected.");
            }
            entry.ExtractToFile(destPath, true);    // ファイルを上書きする
        }
    }
    
    Path.GetFullPath() 함수를 사용하여 병합된 파일 경로를 검증합니다. 지정된 폴더에 없으면 오류로 간주됩니다.[2]
    이번에 나는 예외를 던졌다.
    또한 일반적으로 zip 내의 모든 파일을 펼치는 경우가 많기 때문에 라이브러리에 대응하는 ZipFile.ExtractToDirectory() 함수 등을 사용하는 것이 안전하다.entry.ExtractToFile() 함수는 최대한 사용을 피하는 것이 좋다.

    zip 파일 형식


    zip 파일 끝의 구조체 (중앙 디렉터리) 에는 파일 이름을 저장하는 필드가 있습니다.
    상세한 내용은 참고 사이트[3]를 참조하십시오.
    파일 이름, 포함할 수 없는 문자열에 대한 규정은 이번에 찾았지만 찾지 못했다.
    각주
    Prevent Zip Slip in .NET - Meziantou's blog ↩︎
    단순히 포함되지 않음../이나 ..\의 대책을 확인하는 것만으로는 부족하다.ext4 등 파일 시스템에서는 기호 링크, NTFS도 연결되어 대책을 우회할 수 있다.↩︎
    일본어로 ZIP의 사양·GiitHub 요약 ↩︎

    좋은 웹페이지 즐겨찾기