Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimanakah saya boleh melaksanakan pengekstrakan fail zip yang teguh dan selamat dalam Go, menangani isu yang berpotensi seperti kebocoran deskriptor fail dan kelemahan ZipSlip?

Bagaimanakah saya boleh melaksanakan pengekstrakan fail zip yang teguh dan selamat dalam Go, menangani isu yang berpotensi seperti kebocoran deskriptor fail dan kelemahan ZipSlip?

Patricia Arquette
Patricia Arquetteasal
2024-11-13 06:46:02448semak imbas

How can I implement robust and secure zip file extraction in Go, addressing potential issues like file descriptor leaks and ZipSlip vulnerabilities?

Pengeluaran Fail Zip yang Mudah dengan Go

Menyahzip fail dalam Go boleh menjadi mudah dengan bantuan pakej zip. Dengan menggunakan keupayaannya, anda boleh mengekstrak kandungan arkib termampat dengan mudah.

Kod Asal:

func Unzip(src, dest string) error {
    r, err := zip.OpenReader(src)
    if err != nil {
        return err
    }
    defer r.Close()

    for _, f := range r.File {
        rc, err := f.Open()
        if err != nil {
            return err
        }
        defer rc.Close()

        path := filepath.Join(dest, f.Name)
        if f.FileInfo().IsDir() {
            os.MkdirAll(path, f.Mode())
        } else {
            f, err := os.OpenFile(
                path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
            if err != nil {
                return err
            }
            defer f.Close()

            _, err = io.Copy(f, rc)
            if err != nil {
                return err
            }
        }
    }

    return nil
}

Kod Dipertingkat:

Untuk menambah baik kod dan mengelakkan isu deskriptor fail, pertimbangkan perkara berikut penambahbaikan:

  1. Buat direktori destinasi (dest) jika ia tidak wujud (os.MkdirAll).
  2. Encapsulate pengekstrakan fail dan menulis dalam penutupan untuk menghapuskan tindanan penangguhan . Close() panggilan.
  3. Tambahkan pengendalian ralat pada Close() operasi.
  4. Laksanakan semakan untuk kelemahan ZipSlip (direktori traversal).
func Unzip(src, dest string) error {
    r, err := zip.OpenReader(src)
    if err != nil {
        return err
    }
    defer func() {
        if err := r.Close(); err != nil {
            panic(err)
        }
    }()

    os.MkdirAll(dest, 0755)

    extractAndWriteFile := func(f *zip.File) error {
        rc, err := f.Open()
        if err != nil {
            return err
        }
        defer func() {
            if err := rc.Close(); err != nil {
                panic(err)
            }
        }()

        path := filepath.Join(dest, f.Name)

        if !strings.HasPrefix(path, filepath.Clean(dest) + string(os.PathSeparator)) {
            return fmt.Errorf("illegal file path: %s", path)
        }

        if f.FileInfo().IsDir() {
            os.MkdirAll(path, f.Mode())
        } else {
            os.MkdirAll(filepath.Dir(path), f.Mode())
            f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
            if err != nil {
                return err
            }
            defer func() {
                if err := f.Close(); err != nil {
                    panic(err)
                }
            }()

            _, err = io.Copy(f, rc)
            if err != nil {
                return err
            }
        }
        return nil
    }

    for _, f := range r.File {
        err := extractAndWriteFile(f)
        if err != nil {
            return err
        }
    }

    return nil
}

Dengan peningkatan ini, anda kini boleh menyahzip fail dengan cekap dan selamat dalam Go.

Atas ialah kandungan terperinci Bagaimanakah saya boleh melaksanakan pengekstrakan fail zip yang teguh dan selamat dalam Go, menangani isu yang berpotensi seperti kebocoran deskriptor fail dan kelemahan ZipSlip?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn