| name | go-vuln-dos |
| description | Use when auditing Go code involving goroutine management, channel operations, HTTP request handling, resource allocation, or panic recovery. Covers CWE-400/770/476. Keywords: denial of service, goroutine leak, channel deadlock, panic recover, io.ReadAll, resource exhaustion, OOM, HTTP/2 abuse, protobuf, unbounded allocation, rate limiting |
Go DoS/Resource Exhaustion Vulnerability Patterns (CWE-400/770/476)
当审计 Go 代码中涉及 goroutine 管理、channel 操作、HTTP 请求处理、资源分配、panic 恢复时加载此 Skill。
Detection Strategy
Sources(攻击入口):
- HTTP 请求 body(大 payload、大量并发请求)
- gRPC 消息(protobuf 嵌套深度、repeated 字段大小)
- WebSocket 帧(无限制的消息大小/频率)
- P2P 网络消息(如 go-ethereum 的 peer message)
- 用户控制的分配大小参数
Sinks(资源消耗点):
go func() -- 无限制的 goroutine 创建
make([]byte, userSize) / make([]T, userSize) -- 用户控制的内存分配
io.ReadAll(r) / ioutil.ReadAll(r) -- 读取整个 body 到内存
json.NewDecoder(r).Decode(&v) -- 无大小限制的 JSON 解码
yaml.Unmarshal(data, &v) -- YAML 解码(支持 anchor/alias 指数扩展)
proto.Unmarshal(data, msg) -- protobuf 解码无嵌套限制
panic() 在 HTTP handler 中未被 recover() 捕获
- Channel 操作(
ch <- v 阻塞、<-ch 永久等待)
Sanitization(资源限制屏障):
io.LimitReader(r, maxSize) -- 限制读取大小
http.MaxBytesReader(w, r.Body, maxSize) -- HTTP body 大小限制
context.WithTimeout / context.WithDeadline -- 超时控制
- Goroutine pool(worker pattern,
semaphore.Weighted)
recover() 在 goroutine 入口
- Rate limiting 中间件(
golang.org/x/time/rate)
- Channel 缓冲区大小限制 +
select with default
检测路径:
grep -rn "go func\|go .*(" --include="*.go"
grep -rn "io.ReadAll\|ioutil.ReadAll\|io.Copy" --include="*.go"
grep -rn "make(\[\]byte\|make(\[\]" --include="*.go"
grep -rn "panic(\|recover()" --include="*.go"
grep -rn "json.NewDecoder\|json.Unmarshal\|yaml.Unmarshal\|proto.Unmarshal" --include="*.go"
grep -rn "LimitReader\|MaxBytesReader\|context.WithTimeout" --include="*.go"
grep -rn "make(chan\|<-.*chan" --include="*.go"
- 搜索资源消耗点(goroutine 创建、内存分配、IO 读取、解码操作)
- 追踪输入来源,确认是否来自不可信外部输入
- 验证是否有资源限制:
io.ReadAll 之前是否有 LimitReader/MaxBytesReader?
- Goroutine 是否有退出条件(context cancellation、done channel)?
make([]T, size) 的 size 是否有上限检查?
- HTTP handler 是否有
recover() 中间件防止 panic 导致进程崩溃?
- JSON/protobuf 解码是否限制了嵌套深度或大小?
- 若无资源限制 -> 标记为候选漏洞
Detection Checklist
False Positive Exclusion Guide
以下模式不是此类漏洞:
go func() 在 init() 中启动的后台 worker -- 生命周期与进程相同,不会泄漏
io.ReadAll 读取小文件或内部配置 -- 来源可信且大小可控
panic 用于编程错误检测 -- 如 panic("unreachable") 在 switch default 中
- 带
context.WithTimeout 的 goroutine -- 有超时退出机制
以下模式需要深入检查:
go func() 在 HTTP handler 中 -- 每个请求创建 goroutine 且无 pool 限制
json.Decoder 在 API endpoint -- 未设置 MaxBytesReader 的 HTTP handler
recover() 在 goroutine 内但不在 HTTP handler 链 -- 可能只保护了子 goroutine 但 handler 本身可 panic
select {} 永久阻塞 -- 在某些情况下是有意设计,但也可能是 bug
Real-World Cases
详见 references/cases.md(7 个真实案例,需要时加载)。