printStackTrace 会将栈信息直接打印,因此 printStackTrace() 应替换为日志记录,不应在生产环境中输出到控制台或页面。
try {
// 某些逻辑
} catch (Exception e) {
e.printStackTrace(); // 不安全:会将栈信息直接打印
}
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
try {
// 某些逻辑
} catch (Exception e) {
logger.error("异常发生:{}", e.getMessage(), e); // 日志记录,不暴露到终端
}
扫描工具检测到 MultipartFile 参数时,常误报文件上传漏洞。关键在于是否存在有效的校验逻辑。
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) throws IOException {
file.transferTo(new File("/tmp/" + file.getOriginalFilename())); // 无校验,风险高
return "ok";
}
@PostMapping("/upload")
public String secureUpload(@RequestParam("file") MultipartFile file) throws IOException {
String filename = file.getOriginalFilename();
if (filename == null || !filename.endsWith(".jpg")) {
return "非法文件类型";
}
File dest = new File("/safe/path/" + filename);
file.transferTo(dest);
return "上传成功";
}
MyBatis 中 ${} 占位符在拼接字段名时容易被误判为 SQL 注入。若内容为非字符串且来源受控,通常是误报。
<select id="getUserByField" resultType="User">
SELECT * FROM user WHERE ${field} = #{value}
select>
通过 Java 传参,字段受控:
Map<String, Object> param = new HashMap<>();
param.put("field", "username"); // 固定字段名,非用户可控
param.put("value", "alice");
sqlSession.selectList("getUserByField", param);
后端(Maven):
对于maven构建的Java项目,在项目根目录执行以下命令,生成一个Backendtree.md文件,其中包含Java项目的直接和间接依赖的组件名称和版本号。
mvn dependency:tree > Backendtree.md
前端(npm):
对于前端项目,可在项目根目录执行以下命令,生成一个FrontendTree.md文件,其中包含前端组件的直接和间接依赖的名称和版本号。
npm ll --depth=5 > FrontendTree.md
示例:
[INFO] +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.6:compile
[INFO] | \- com.fasterxml.jackson.core:jackson-core:jar:2.9.6:compile
在项目中,有两类依赖:
直接依赖:你在 pom.xml 或 package.json 中手动写明的依赖;
间接依赖:你的直接依赖又依赖的组件,即“依赖的依赖”。
假设你项目依赖了组件 A,但组件 A 又依赖了一个有漏洞的老版本组件 B:1.0.0,这时你项目其实是间接使用了组件 B:1.0.0,并可能被扫描工具提示漏洞。
若漏洞来源于间接依赖组件,可通过提升为直接依赖来覆盖旧版本。
对于直接依赖组件,可在 Java - pom.xml 显式声明新版本:
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.13.4.2version>
dependency>
对于间接依赖组件,可以在 pom.xml 里手动添加一个安全版本的 B 组件(比如 B:2.0.0),即使代码中并没有直接使用它。
Maven 构建时,会优先使用你直接声明的版本 B:2.0.0,从而覆盖掉旧的间接依赖版本 B:1.0.0,达到漏洞修复目的。
前端 - npm 升级组件:
npm uninstall lodash
npm install [email protected]
前端强制锁版本:
"resolutions": {
"lodash": "4.17.21"
}
扫描工具在检测到返回 HTML 内容时,若包含用户输入的字段,常会报出 XSS 漏洞。但若使用了模板引擎自动转义或框架默认做了输出编码处理,往往属于误报。
@GetMapping("/greet")
public String greet(@RequestParam String name) {
return "Hello " + name + ""; // 无任何转义,存在XSS风险
}
<p th:text="'Hello ' + ${name}">p>
工具在扫描 API 接口时,若未发现显式鉴权代码或注解(如 @PreAuthorize
、@RequiresPermissions
),可能误报为“接口未鉴权”。但实际很多接口已在网关、拦截器层进行了统一校验。
@GetMapping("/user/info")
public User getInfo() {
return userService.getCurrentUser(); // 无注解,工具可能误报
}
在接口方法上增加显式鉴权注解,增强工具识别度:
@PreAuthorize("hasRole('USER')")
@GetMapping("/user/info")
public User getInfo() {
return userService.getCurrentUser();
}
或者,在安全配置类中集中定义权限策略,并在文档中说明统一鉴权逻辑。
扫描工具若检测到存在读取文件路径的逻辑,尤其是拼接路径或传入 filename 参数时,会默认判定为路径遍历风险。
@GetMapping("/file")
public String read(@RequestParam String name) throws IOException {
return Files.readString(Paths.get("/data/" + name)); // 用户可控
}
添加路径白名单与规范化:
@GetMapping("/file")
public String safeRead(@RequestParam String name) throws IOException {
Path basePath = Paths.get("/data").toAbsolutePath().normalize();
Path filePath = basePath.resolve(name).normalize();
if (!filePath.startsWith(basePath)) {
throw new SecurityException("非法访问路径");
}
return Files.readString(filePath);
}
修复建议:
location ~* \.(yaml|yml|properties|env|xml)$ {
deny all;
}
Spring Boot 应配置静态资源路径明确,不应自动映射 /resources/ 或 /config/ 为 web 访问路径。
工具检测到参数中包含跳转链接(如 url=xxx),会默认判断为 Open Redirect 漏洞。需判断跳转目标是否为白名单内地址。
@GetMapping("/redirect")
public void redirect(@RequestParam String url, HttpServletResponse response) throws IOException {
response.sendRedirect(url); // 用户可控,存在跳转风险
}
@GetMapping("/redirect")
public void safeRedirect(@RequestParam String url, HttpServletResponse response) throws IOException {
List<String> whitelist = List.of("https://www.safe.com", "https://app.safe.com");
if (whitelist.stream().anyMatch(url::startsWith)) {
response.sendRedirect(url);
} else {
response.sendError(403, "非法跳转地址");
}
}