跳转至

Spring Boot 安全审查

在添加认证、处理输入、创建端点或处理机密时使用。

认证

  • 优先使用无状态 JWT 或带吊销列表的不透明令牌
  • 会话使用 httpOnly、Secure、SameSite=Strict Cookie
  • 在 OncePerRequestFilter 或资源服务器中验证令牌
@Component
public class JwtAuthFilter extends OncePerRequestFilter {
  private final JwtService jwtService;

  public JwtAuthFilter(JwtService jwtService) {
    this.jwtService = jwtService;
  }

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
      FilterChain chain) throws ServletException, IOException {
    String header = request.getHeader(HttpHeaders.AUTHORIZATION);
    if (header != null && header.startsWith("Bearer ")) {
      String token = header.substring(7);
      Authentication auth = jwtService.authenticate(token);
      SecurityContextHolder.getContext().setAuthentication(auth);
    }
    chain.doFilter(request, response);
  }
}

授权

  • 启用方法安全: @EnableMethodSecurity
  • 使用 @PreAuthorize("hasRole('ADMIN')") 或 @PreAuthorize("@authz.canEdit(#id)")
  • 默认拒绝,仅公开所需的作用域

输入验证

  • 在控制器中使用 @Valid 进行 Bean Validation
  • 在 DTO 上应用约束: @NotBlank、@Email、@Size、自定义验证器
  • 渲染前使用白名单对 HTML 进行净化

SQL 注入防护

  • 使用 Spring Data 仓库或参数化查询
  • 原生查询使用 :param 绑定,不要拼接字符串

CSRF 防护

  • 对于浏览器会话应用,启用 CSRF,并在表单/请求头中包含令牌
  • 对于使用 Bearer 令牌的纯 API,禁用 CSRF 并依赖无状态认证
http
  .csrf(csrf -> csrf.disable())
  .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

机密管理

  • 不要在源代码中包含机密。从环境变量或 vault 读取
  • 将 application.yml 与凭据分离,使用占位符
  • 定期轮换令牌和数据库凭据

安全头

http
  .headers(headers -> headers
    .contentSecurityPolicy(csp -> csp
      .policyDirectives("default-src 'self'"))
    .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)
    .xssProtection(Customizer.withDefaults())
    .referrerPolicy(rp -> rp.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.NO_REFERRER)));

速率限制

  • 对高成本端点应用 Bucket4j 或网关级限制
  • 记录突发并发送告警,返回带重试提示的 429

依赖项安全

  • 在 CI 中运行 OWASP Dependency Check / Snyk
  • 保持 Spring Boot 和 Spring Security 在受支持的版本
  • 让已知 CVE 导致构建失败

日志与 PII

  • 不要记录机密、令牌、密码或完整 PAN 数据
  • 对敏感字段进行脱敏,并使用结构化 JSON 日志

文件上传

  • 验证大小、内容类型和扩展名
  • 保存到 Web 根目录之外,必要时进行扫描

发布前检查清单

  • [ ] 认证令牌被正确验证且已过期
  • [ ] 所有机密路径都有授权保护
  • [ ] 所有输入都经过验证和净化
  • [ ] 没有字符串拼接的 SQL
  • [ ] 针对应用类型的 CSRF 防护正确
  • [ ] 机密已外部化且未被提交
  • [ ] 已设置安全头
  • [ ] API 有速率限制
  • [ ] 依赖项已扫描且为最新
  • [ ] 日志中没有机密数据

注意: 默认拒绝,验证输入,应用最小权限,并优先采用基于配置的安全措施。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 ev/ECC