簡體   English   中英

G110:減壓炸彈的潛在 DoS 漏洞 (gosec)

[英]G110: Potential DoS vulnerability via decompression bomb (gosec)

我收到以下golintci消息:

testdrive/utils.go:92:16: G110: Potential DoS vulnerability via decompression bomb (gosec)
    if _, err := io.Copy(targetFile, fileReader); err != nil {
                 ^

閱讀相應的CWE ,我不清楚如何糾正這一點。

請指點。

func unzip(archive, target string) error {
    reader, err := zip.OpenReader(archive)
    if err != nil {
        return err
    }

    for _, file := range reader.File {
        path := filepath.Join(target, file.Name) // nolint: gosec
        if file.FileInfo().IsDir() {
            if err := os.MkdirAll(path, file.Mode()); err != nil {
                return err
            }
            continue
        }

        fileReader, err := file.Open()
        if err != nil {
            return err
        }
        defer fileReader.Close() // nolint: errcheck

        targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
        if err != nil {
            return err
        }
        defer targetFile.Close() // nolint: errcheck

        if _, err := io.Copy(targetFile, fileReader); err != nil {
            return err
        }
    }

    return nil
}

您收到的警告來自gosec中提供的規則。

該規則專門檢測文件解壓縮時io.Copy的使用情況。

這是一個潛在問題,因為io.Copy

src復制到dst直到在src上達到 EOF 或發生錯誤。

因此,惡意負載可能會導致您的程序從 memory 中解壓出意外的大量數據和 go,從而導致警告消息中提到的拒絕服務。

特別是,gosec 將檢查( source )您的程序的 AST 並警告您使用io.Copyio.CopyBuffer以及以下任何一項:

  • "compress/gzip".NewReader
  • "compress/zlib".NewReaderNewReaderDict
  • "compress/bzip2".NewReader
  • "compress/flate".NewReaderNewReaderDict
  • "compress/lzw".NewReader
  • "archive/tar".NewReader
  • "archive/zip".NewReader
  • "*archive/zip".File.Open

使用io.CopyN刪除警告,因為(引用)它“將n 個字節(或直到出現錯誤)從 src 復制到 dst ”,從而讓您(程序編寫者)控制要復制的字節數。 因此,您可以根據應用程序的可用資源設置任意大的n ,或者復制 chunks

基於提供的各種指針,替換

        if _, err := io.Copy(targetFile, fileReader); err != nil {
            return err
        }

        for {
            _, err := io.CopyN(targetFile, fileReader, 1024)
            if err != nil {
                if err == io.EOF {
                    break
                }
                return err
            }
        }

PS 雖然這有助於 memory 占用空間,但這無助於 DDOS 攻擊復制非常長和/或無限的 stream ...

假設您正在處理壓縮數據,則需要使用io.CopyN
您可以嘗試使用--nocompress標志的解決方法。 但這會導致數據未壓縮。

請參閱以下 PR 和相關問題: https://github.com/go-bindata/go-bindata/pull/50

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM