Heim  >  Artikel  >  Backend-Entwicklung  >  Wie kann ich eine robuste und sichere ZIP-Dateiextraktion in Go implementieren und so potenzielle Probleme wie Dateideskriptorlecks und ZipSlip-Schwachstellen beheben?

Wie kann ich eine robuste und sichere ZIP-Dateiextraktion in Go implementieren und so potenzielle Probleme wie Dateideskriptorlecks und ZipSlip-Schwachstellen beheben?

Patricia Arquette
Patricia ArquetteOriginal
2024-11-13 06:46:02451Durchsuche

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

Mühelose Zip-Dateiextraktion mit Go

Das Entpacken von Dateien in Go kann mit Hilfe des Zip-Pakets ein Kinderspiel sein. Durch die Nutzung seiner Funktionen können Sie den Inhalt komprimierter Archive problemlos extrahieren.

Originalcode:

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
}

Erweiterter Code:

Um den Code weiter zu verbessern und Dateideskriptorprobleme zu vermeiden, ziehen Sie die folgenden Verbesserungen in Betracht:

  1. Erstellen Sie das Zielverzeichnis (dest), wenn es nicht existiert (os.MkdirAll).
  2. Kapseln Sie das Extrahieren und Schreiben von Dateien in einem Abschluss, um das Stapeln von defer .Close()-Aufrufen zu vermeiden.
  3. Fügen Sie Fehlerbehandlung zu Close()-Vorgängen hinzu.
  4. Implementieren Sie eine Prüfung für ZipSlip ( (Directory Traversal)-Schwachstellen.
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
}

Mit diesen Verbesserungen können Sie Dateien jetzt effizient und sicher in Go entpacken.

Das obige ist der detaillierte Inhalt vonWie kann ich eine robuste und sichere ZIP-Dateiextraktion in Go implementieren und so potenzielle Probleme wie Dateideskriptorlecks und ZipSlip-Schwachstellen beheben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn