Maison > développement back-end > Golang > Comment puis-je simplifier et sécuriser la décompression de fichiers à l'aide du package zip de Go ?

Comment puis-je simplifier et sécuriser la décompression de fichiers à l'aide du package zip de Go ?

Barbara Streisand
Libérer: 2024-11-14 14:54:02
original
412 Les gens l'ont consulté

How can I simplify and secure file decompression using Go's zip package?

Décompression de fichiers simple et efficace dans Go

La décompression des archives ZIP dans Go peut être un processus simple. Une approche, comme le démontre le code d'origine, consiste à gérer manuellement la décompression pour chaque fichier de l'archive.

Cependant, il existe un moyen plus transparent et plus efficace d'y parvenir en utilisant la solution mise à jour suivante :

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)

    // Closure to wrap file extraction and writing, avoiding deferred stack overflow
    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)

        // Check for directory traversal (ZipSlip) vulnerability
        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

Cette solution mise à jour offre plusieurs avantages :

  • Erreurs de fermeture différée () gérées : Elle gère gracieusement les erreurs potentielles lors de la fermeture du lecteur de fichiers (rc) et du lecteur d'archives (r), garantissant un nettoyage approprié même en cas de pannes.
  • Extraction de fichiers emballés avec fermeture : Le processus d'extraction et d'écriture de chaque fichier est encapsulé dans une fermeture, éliminant ainsi le besoin d'empiler et de nettoyer plusieurs appels defer .Close() pour chaque fichier.
  • Création de répertoire : La solution garantit que le répertoire de destination existe avant l'extraction des fichiers, évitant ainsi tout échec d'extraction.
  • Prévention Zipslip : Il comprend un contrôle de sécurité pour empêcher les vulnérabilités potentielles de traversée de répertoire (Zipslip) en vérifiant que les fichiers ne sont pas extraits en dehors du répertoire de destination attendu.

Avec ces améliorations, ce code fournit une méthode simple, robuste et sécurisée pour décompresser des fichiers 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