CodeQL 文档

切片内存分配的大小值过大

ID: go/uncontrolled-allocation-size
Kind: path-problem
Security severity: 7.5
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-770
Query suites:
   - go-code-scanning.qls
   - go-security-extended.qls
   - go-security-and-quality.qls

点击查看 CodeQL 存储库中的查询

使用不受信任的输入通过内置 make 函数分配切片可能会导致过多的内存分配,并可能由于内存不足而导致程序崩溃。此漏洞可被利用来执行拒绝服务攻击,方法是消耗所有可用的服务器资源。

建议

对使用内置 make 函数进行的大小分配实现最大允许值,以防止过大的分配。

示例

在以下代码片段中,n 参数由用户控制。

如果外部用户提供过大的值,应用程序会在没有进一步验证的情况下分配大小为 n 的切片,这可能会耗尽所有可用内存。

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
)

func OutOfMemoryBad(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query()

	queryStr := query.Get("n")
	collectionSize, err := strconv.Atoi(queryStr)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	result := make([]string, collectionSize)
	for i := 0; i < collectionSize; i++ {
		result[i] = fmt.Sprintf("Item %d", i+1)
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(result)
}

防止此漏洞的一种方法是对用户控制的输入实现最大允许值,如下例所示

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
)

func OutOfMemoryGood(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query()
	MaxValue := 6
	queryStr := query.Get("n")
	collectionSize, err := strconv.Atoi(queryStr)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	if collectionSize < 0 || collectionSize > MaxValue {
		http.Error(w, "Bad request", http.StatusBadRequest)
		return
	}
	result := make([]string, collectionSize)
	for i := 0; i < collectionSize; i++ {
		result[i] = fmt.Sprintf("Item %d", i+1)
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(result)
}

参考

  • ©2025GitHub, Inc.
  • 条款
  • 隐私