springboot-security
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSpring Boot Security Review
Spring Boot Security 安全审查
Use when adding auth, handling input, creating endpoints, or dealing with secrets.
适用于添加认证、处理输入、创建端点或管理密钥的场景。
Authentication
认证
- Prefer stateless JWT or opaque tokens with revocation list
- Use ,
httpOnly,Securecookies for sessionsSameSite=Strict - Validate tokens with or resource server
OncePerRequestFilter
java
@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);
}
}- 优先使用带吊销列表的无状态JWT或不透明令牌
- 会话使用、
httpOnly、Secure类型的CookieSameSite=Strict - 使用或资源服务器验证令牌
OncePerRequestFilter
java
@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);
}
}Authorization
授权
- Enable method security:
@EnableMethodSecurity - Use or
@PreAuthorize("hasRole('ADMIN')")@PreAuthorize("@authz.canEdit(#id)") - Deny by default; expose only required scopes
- 启用方法级安全:
@EnableMethodSecurity - 使用或
@PreAuthorize("hasRole('ADMIN')")注解@PreAuthorize("@authz.canEdit(#id)") - 默认拒绝所有请求,仅开放必要的权限范围
Input Validation
输入验证
- Use Bean Validation with on controllers
@Valid - Apply constraints on DTOs: ,
@NotBlank,@Email, custom validators@Size - Sanitize any HTML with a whitelist before rendering
- 在控制器中结合使用Bean Validation
@Valid - 在DTO上应用约束注解:、
@NotBlank、@Email或自定义验证器@Size - 在渲染前使用白名单清理所有HTML内容
SQL Injection Prevention
SQL注入防护
- Use Spring Data repositories or parameterized queries
- For native queries, use bindings; never concatenate strings
:param
- 使用Spring Data仓库或参数化查询
- 原生查询使用绑定;绝不要拼接字符串
:param
CSRF Protection
CSRF防护
- For browser session apps, keep CSRF enabled; include token in forms/headers
- For pure APIs with Bearer tokens, disable CSRF and rely on stateless auth
java
http
.csrf(csrf -> csrf.disable())
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS));- 对于基于浏览器会话的应用,保持CSRF启用;在表单或请求头中包含CSRF令牌
- 对于使用Bearer令牌的纯API,禁用CSRF并依赖无状态认证
java
http
.csrf(csrf -> csrf.disable())
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS));Secrets Management
密钥管理
- No secrets in source; load from env or vault
- Keep free of credentials; use placeholders
application.yml - Rotate tokens and DB credentials regularly
- 源代码中不要存放密钥;从环境变量或密钥管理服务加载
- 中不要包含凭证;使用占位符
application.yml - 定期轮换令牌和数据库凭证
Security Headers
安全头
java
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)));java
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)));Rate Limiting
限流
- Apply Bucket4j or gateway-level limits on expensive endpoints
- Log and alert on bursts; return 429 with retry hints
- 对资源消耗大的端点使用Bucket4j或网关级限流
- 对流量突发情况进行日志记录和告警;返回429状态码并附带重试提示
Dependency Security
依赖安全
- Run OWASP Dependency Check / Snyk in CI
- Keep Spring Boot and Spring Security on supported versions
- Fail builds on known CVEs
- 在CI流程中运行OWASP Dependency Check或Snyk
- 保持Spring Boot和Spring Security为受支持的版本
- 若存在已知CVE漏洞则终止构建
Logging and PII
日志与敏感数据
- Never log secrets, tokens, passwords, or full PAN data
- Redact sensitive fields; use structured JSON logging
- 绝不要记录密钥、令牌、密码或完整的PAN数据
- 对敏感字段进行脱敏;使用结构化JSON日志
File Uploads
文件上传
- Validate size, content type, and extension
- Store outside web root; scan if required
- 验证文件大小、内容类型和扩展名
- 存储在Web根目录之外;必要时进行扫描
Checklist Before Release
发布前检查清单
- Auth tokens validated and expired correctly
- Authorization guards on every sensitive path
- All inputs validated and sanitized
- No string-concatenated SQL
- CSRF posture correct for app type
- Secrets externalized; none committed
- Security headers configured
- Rate limiting on APIs
- Dependencies scanned and up to date
- Logs free of sensitive data
Remember: Deny by default, validate inputs, least privilege, and secure-by-configuration first.
- 认证令牌已正确验证和过期
- 每个敏感路径都有授权防护
- 所有输入已验证和清理
- 无字符串拼接的SQL语句
- 根据应用类型正确配置CSRF策略
- 密钥已外部化,无密钥提交到代码仓库
- 已配置安全头
- API已配置限流
- 依赖已扫描且为最新版本
- 日志中无敏感数据
注意:默认拒绝所有请求,验证所有输入,遵循最小权限原则,优先通过配置实现安全。