Maison > développement back-end > Golang > Comment puis-je mettre en œuvre une extraction de fichiers zip robuste et sécurisée dans Go, en résolvant des problèmes potentiels tels que les fuites de descripteurs de fichiers et les vulnérabilités Zipslip ?

Comment puis-je mettre en œuvre une extraction de fichiers zip robuste et sécurisée dans Go, en résolvant des problèmes potentiels tels que les fuites de descripteurs de fichiers et les vulnérabilités Zipslip ?

Patricia Arquette
Libérer: 2024-11-13 06:46:02
original
496 Les gens l'ont consulté

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

Extraction de fichiers Zip sans effort avec Go

Décompresser des fichiers dans Go peut être un jeu d'enfant avec l'aide du package zip. En utilisant ses capacités, vous pouvez facilement extraire le contenu des archives compressées.

Code original :

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
}
Copier après la connexion

Code amélioré :

Pour améliorer davantage le code et éviter les problèmes de descripteur de fichier, considérez ce qui suit améliorations :

  1. Créez le répertoire de destination (dest) s'il n'existe pas (os.MkdirAll).
  2. Encapsulez l'extraction et l'écriture de fichiers dans une fermeture pour éliminer l'empilement de defer . Appels Close().
  3. Ajouter la gestion des erreurs aux opérations Close().
  4. Implémenter une vérification pour Zipslip (traversée de répertoire).
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
}
Copier après la connexion

Grâce à ces améliorations, vous pouvez désormais décompresser des fichiers de manière efficace et sécurisée dans Go.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal