Springboot Security

affaan-m/ECC/.kiro/skills/springboot-security

作者 affaan-mef648e01899ba3e8dc6371642deaaf64b4477775無授權條款275K 個星標收錄於 2026年10月9日更新於 2026年10月9日儲存庫4 天前更新

Spring Security best practices for authn/authz, validation, CSRF, secrets, headers, rate limiting, and dependency security in Java Spring Boot services.

僅含說明Security
AI 產生的概覽

Spring Boot 安全性審查指南,涵蓋驗證、授權、輸入檢查、CSRF、密鑰、標頭、限流與相依性檢查。

功能
此技能為 Java Spring Boot 服務的安全性強化提供審查清單與程式碼範例。內容涵蓋驗證篩選器、方法層級授權、輸入驗證、SQL 注入防範、密碼雜湊、CSRF 策略、密鑰外部化、安全標頭、CORS、限流、相依性掃描、日誌去識別化以及檔案上傳。產出的是指引說明與附註解的 Java、YAML 範例,而非可執行的成品。
適用情境
當你要為 Spring Boot 服務加入驗證或授權、處理使用者輸入、建立端點或管理密鑰時使用。也適合在發佈前審查 CORS、CSRF、安全標頭、限流與相依性漏洞。
執行需求
不需要任何指令碼或工具,僅為說明性內容。範例假定有一個使用 Spring Security 的 Java Spring Boot 專案,並提及 Bucket4j、Spring Cloud Vault、OWASP Dependency Check 與 Snyk 等選用函式庫與服務。

Spring Boot Security Review

Use when adding auth, handling input, creating endpoints, or dealing with secrets.

When to Activate

  • Adding authentication (JWT, OAuth2, session-based)
  • Implementing authorization (@PreAuthorize, role-based access)
  • Validating user input (Bean Validation, custom validators)
  • Configuring CORS, CSRF, or security headers
  • Managing secrets (Vault, environment variables)
  • Adding rate limiting or brute-force protection
  • Scanning dependencies for CVEs

Authentication

  • Prefer stateless JWT or opaque tokens with revocation list
  • Use httpOnly, Secure, SameSite=Strict cookies for sessions
  • Validate tokens with OncePerRequestFilter or resource server
java
@Componentpublic 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 @PreAuthorize("hasRole('ADMIN')") or @PreAuthorize("@authz.canEdit(#id)")
  • Deny by default; expose only required scopes
java
@RestController@RequestMapping("/api/admin")public class AdminController {
  @PreAuthorize("hasRole('ADMIN')")  @GetMapping("/users")  public List<UserDto> listUsers() {    return userService.findAll();  }
  @PreAuthorize("@authz.isOwner(#id, authentication)")  @DeleteMapping("/users/{id}")  public ResponseEntity<Void> deleteUser(@PathVariable Long id) {    userService.delete(id);    return ResponseEntity.noContent().build();  }}

Input Validation

  • Use Bean Validation with @Valid on controllers
  • Apply constraints on DTOs: @NotBlank, @Email, @Size, custom validators
  • Sanitize any HTML with a whitelist before rendering
java
// BAD: No validation@PostMapping("/users")public User createUser(@RequestBody UserDto dto) {  return userService.create(dto);}
// GOOD: Validated DTOpublic record CreateUserDto(    @NotBlank @Size(max = 100) String name,    @NotBlank @Email String email,    @NotNull @Min(0) @Max(150) Integer age) {}
@PostMapping("/users")public ResponseEntity<UserDto> createUser(@Valid @RequestBody CreateUserDto dto) {  return ResponseEntity.status(HttpStatus.CREATED)      .body(userService.create(dto));}

SQL Injection Prevention

  • Use Spring Data repositories or parameterized queries
  • For native queries, use :param bindings; never concatenate strings
java
// BAD: String concatenation with EntityManager (SQL injection risk)String sql = "SELECT * FROM users WHERE name = '" + name + "'";List<User> users = entityManager.createNativeQuery(sql, User.class).getResultList();
// GOOD: Parameterized native query@Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true)List<User> findByName(@Param("name") String name);
// GOOD: Spring Data derived query (auto-parameterized)List<User> findByEmailAndActiveTrue(String email);

Password Encoding

  • Always hash passwords with BCrypt or Argon2 — never store plaintext
  • Use PasswordEncoder bean, not manual hashing
java
@Beanpublic PasswordEncoder passwordEncoder() {  return new BCryptPasswordEncoder(12); // cost factor 12}
// In servicepublic User register(CreateUserDto dto) {  String hashedPassword = passwordEncoder.encode(dto.password());  return userRepository.save(new User(dto.email(), hashedPassword));}

CSRF Protection

  • 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));

Secrets Management

  • No secrets in source; load from env or vault
  • Keep application.yml free of credentials; use placeholders
  • Rotate tokens and DB credentials regularly
yaml
# BAD: Hardcoded in application.ymlspring:  datasource:    password: mySecretPassword123
# GOOD: Environment variable placeholderspring:  datasource:    password: ${DB_PASSWORD}
# GOOD: Spring Cloud Vault integrationspring:  cloud:    vault:      uri: https://vault.example.com      token: ${VAULT_TOKEN}

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)));

CORS Configuration

  • Configure CORS at the security filter level, not per-controller
  • Restrict allowed origins — never use * in production
java
@Beanpublic CorsConfigurationSource corsConfigurationSource() {  CorsConfiguration config = new CorsConfiguration();  config.setAllowedOrigins(List.of("https://app.example.com"));  config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));  config.setAllowedHeaders(List.of("Authorization", "Content-Type"));  config.setAllowCredentials(true);  config.setMaxAge(3600L);
  UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  source.registerCorsConfiguration("/api/**", config);  return source;}
// In SecurityFilterChain:http.cors(cors -> cors.configurationSource(corsConfigurationSource()));

Rate Limiting

  • Apply Bucket4j or gateway-level limits on expensive endpoints
  • Log and alert on bursts; return 429 with retry hints
java
// Using Bucket4j for per-endpoint rate limiting@Componentpublic class RateLimitFilter extends OncePerRequestFilter {  private final Map<String, Bucket> buckets = new ConcurrentHashMap<>();
  private Bucket createBucket() {    return Bucket.builder()        .addLimit(Bandwidth.classic(100, Refill.intervally(100, Duration.ofMinutes(1))))        .build();  }
  @Override  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,      FilterChain chain) throws ServletException, IOException {    String clientIp = request.getRemoteAddr();    Bucket bucket = buckets.computeIfAbsent(clientIp, k -> createBucket());
    if (bucket.tryConsume(1)) {      chain.doFilter(request, response);    } else {      response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());      response.getWriter().write("{\"error\": \"Rate limit exceeded\"}");    }  }}

Dependency Security

  • Run OWASP Dependency Check / Snyk in CI
  • Keep Spring Boot and Spring Security on supported versions
  • Fail builds on known CVEs

Logging and PII

  • Never log secrets, tokens, passwords, or full PAN data
  • Redact sensitive fields; use structured JSON logging

File Uploads

  • Validate size, content type, and extension
  • Store outside web root; scan if required

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.

來源與署名

來源:affaan-m/ECC位於.kiro/skills/springboot-security提交ef648e0

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架