Checkmarx检测Heap Inspection:oldPassword未清内存是否为误报?
Checkmarx检测结果是否为误报?
结论:这个检测结果不是误报,但实际风险需要结合运行环境评估。
原因分析
Java的String是不可变类型,一旦明文密码被赋值给oldPassword和newPassword变量,内存里的明文内容就无法直接被覆盖。这两个变量的引用会留在方法的栈帧中,直到changePassword方法执行完毕、变量被垃圾回收(GC)之前,恶意工具可以通过内存dump的方式读取到这些明文密码。
你的代码里,这两个密码变量在调用userDetails.changeUserPassword之后就不再使用,但它们的引用依然存在,内存中的明文密码不会立即消失,完全符合Checkmarx的检测规则。
优化建议
如果要消除告警并降低风险,可以改用可变字符数组(char[])存储密码,使用完毕后手动覆盖内存内容:
@PutMapping(path = "/changepassword", produces = APPLICATION_JSON_VALUE) public ResponseEntity<String> changePassword(@RequestBody UserUpdate user, HttpServletRequest request, HttpServletResponse response) { String uid= user.getId(); char[] oldPassword = user.getOldPwrd().toCharArray(); char[] newPassword = user.getPwrd().toCharArray(); try { userDetails.changeUserPassword(uid, new String(oldPassword), new String(newPassword)); } finally { // 使用后清空字符数组,覆盖内存中的明文 Arrays.fill(oldPassword, '\0'); Arrays.fill(newPassword, '\0'); } return ResponseEntity.ok(SUCCESS); }
注意:如果UserUpdate类的getOldPwrd()和getPwrd()返回的本身就是String,那最初的String对象还是会留在内存里,最好从请求解析阶段就用char[]处理密码数据,从源头减少明文暴露的时间。
内容的提问来源于stack exchange,提问作者Deepak
相关产品推荐
相关产品推荐

