代码安全审计中常常会用到审计工具帮助提升审计效率和效果,但受限于审计规则或漏洞规则,审计结果也需要人工分析和排查,排除结果中的漏洞误报,并给出合理的漏洞修复方案。
本文根据实际Java代码审计项目的人工分析和排查经验,总结了工具扫描结果的常见误报类型以及修复方案缺陷,同时也给出相应合理的修复方式。
1. 文件上传漏洞误报
对于带了文件参数是MultipartFile的入口,工具基本会认为就是上传漏洞(即使代码中已经对上传文件做了合法性校验),因此这类的上传漏洞误报率比较高。
2. SQL注入漏洞误报
Java语言MyBatis框架中使用${}进行SQL语句的拼接,由于该类型的占位符不会做预编译处理,因此工具会报出SQL注入,但代码中该占位符如果是本身无需预编译的值,如数据库表的字段、config.properties配置文件的属性名,或者该占位符的内容不是String类型,则不存在SQL注入。
下面的示例代码中,SQL语句中的${}占位符是两个实体类的字段,而SQL注入的payload需是字符串类型(形如’ OR IF(SLEEP(5), 0, 1) –的字符串),数据类型不匹配无法进行注入,所以这里是SQL注入漏洞的误报。
3. 硬编码漏洞的修复
对于硬编码漏洞可以用诸如Jasypt的工具类对代码、配置文件中的密钥、密码等做加密处理。
4. 系统信息泄露的修复
以下图为例,图中代码因使用了printStackTrace()方法而被工具提示为系统信息泄露漏洞。
但是修复方案中没有给出具体的修复方法。
一般可以使用专用的日志工具,如slf4j组件的logger替换printStackTrace处理异常。
5. 组件漏洞推荐版本缺失
在开源组件漏洞检测中,工具扫描的漏洞结果里有时会缺少推荐版本的信息。这种情况可以在GitHub的漏洞库(https://github.com/advisories)中搜索该组件的CVE编号,从而查看官方推荐的版本信息。
6. 组件间接依赖的误报
如果第三方组件的间接依赖(可能)存在版本误报,可以使用项目的Backendtree.md和FrontendTree.md文件,生成方法如下。
对于maven构建的Java项目,在项目根目录执行命令mvn dependency:tree >Backendtree.md,生成一个Backendtree.md文件,其中包含Java项目的直接和间接依赖的组件名称和版本号。
对于前端项目,可在项目根目录执行npm ll –depth=5 >FrontendTree.md,生成一个FrontendTree.md文件,其中包含前端组件的直接和间接依赖的名称和版本号。
最后可以根据Backendtree.md和FrontendTree.md里面的间接依赖版本排除误报。
7. 间接依赖组件的升级
对于直接依赖组件的漏洞修复,方法之一是做版本升级,这时直接修改依赖版本号升级即可。
对于间接依赖组件的漏洞给修复,如果是通过版本升级修复,可以单独引用这个间接依赖的组件坐标,将其作为直接依赖使用,它的优先级会比间接依赖高,从而在组件引用组件时优先使用该版本的组件。
对于前端组件,可以用npm uninstall卸载存在漏洞的组件,再用npm install < package-name >@重新安装安全版本的组件。
作者:RoShine
2023年10月27日
洞源实验室