Checkmarx扫描报http.Get存在DoS资源耗尽风险,getParams函数是否有隐患?
结论
该getParams函数确实存在潜在的资源耗尽风险,和Checkmarx的扫描提示吻合,风险主要来自以下几个方面:
- 缺少请求超时控制:
http.Get默认使用全局无超时的http.Client,一旦出现网络波动、目标服务响应缓慢的情况,请求会一直挂起,占用TCP连接资源不释放。你在遍历列表批量调用该函数时,会快速耗尽可用的TCP连接、文件描述符,最终导致后续所有网络请求都无法发起。 - 默认连接池无合理上限控制:默认
http.Transport对单域名的最大连接数限制较宽松,高并发调用该函数时,会无节制新建TCP连接,进一步加剧资源耗尽的问题。 - 错误处理逻辑不完善:调用
ioutil.ReadAll读取出错后仅打印日志,未提前终止函数执行,后续无意义的JSON反序列化逻辑属于无效资源消耗,虽然不直接引发资源耗尽,但会放大高并发下的资源占用问题。
修复方案
可以通过以下修改彻底解决资源耗尽风险:
- 自定义带超时的
http.Client,禁止直接使用默认的http.Get:
// 全局初始化一次即可,不要每次调用函数都新建Client var httpClient = &http.Client{ Timeout: 5 * time.Second, // 根据业务场景设置合理的超时时间 Transport: &http.Transport{ MaxIdleConns: 50, MaxIdleConnsPerHost: 10, MaxConnsPerHost: 20, // 限制单域名最大连接数 IdleConnTimeout: 30 * time.Second, }, } // 函数内替换http.Get为自定义客户端的Get方法 resp, err := httpClient.Get(url)
- 完善错误处理逻辑,读取响应body出错后直接返回,避免执行后续无效逻辑:
body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Error(err.Error(), err) return -1.0, -1.0, err // 新增错误返回 }
- 批量调用该函数时增加并发控制,比如用带缓冲的Channel限制同时发起的请求数不超过连接池配置的上限,从源头控制资源占用。
内容的提问来源于stack exchange,提问作者chancyWu
相关产品推荐
相关产品推荐

