Source profileQuality 78/100

affaan-m/ECC/skills/springboot-security/SKILL.md

springboot-security

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

Source repository stars
234,327
Declared platforms
0
Static risk flags
1
Last source update
2026-07-27
Source checked
2026-07-28

Decision brief

What it does—and where it fits

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

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/affaan-m/ECC --skill "skills/springboot-security"
    Safe inspection promptEditorial

    Inspect the Agent Skill "springboot-security" from https://github.com/affaan-m/ECC/blob/4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38/skills/springboot-security/SKILL.md at commit 4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      When to Activate

      Adding authentication (JWT, OAuth2, session-based)

      Adding authentication (JWT, OAuth2, session-based)Implementing authorization (@PreAuthorize, role-based access)Validating user input (Bean Validation, custom validators)
    2. 02

      Authentication

      Prefer stateless JWT or opaque tokens with revocation list

      Prefer stateless JWT or opaque tokens with revocation listUse httpOnly, Secure, SameSite=Strict cookies for sessionsValidate tokens with OncePerRequestFilter or resource server
    3. 03

      Authorization

      Enable method security: @EnableMethodSecurity

      Enable method security: @EnableMethodSecurityUse @PreAuthorize("hasRole('ADMIN')") or @PreAuthorize("@authz.canEdit(id)")Deny by default; expose only required scopes
    4. 04

      Input Validation

      Use Bean Validation with @Valid on controllers

      Use Bean Validation with @Valid on controllersApply constraints on DTOs: @NotBlank, @Email, @Size, custom validatorsSanitize any HTML with a whitelist before rendering
    5. 05

      SQL Injection Prevention

      Use Spring Data repositories or parameterized queries

      Use Spring Data repositories or parameterized queriesFor native queries, use :param bindings; never concatenate strings- Use Spring Data repositories or parameterized queries - For native queries, use :param bindings; never concatenate strings

    Permission review

    Static risk signals and limitations

    Network access

    medium · line 164

    The documentation includes network, browsing, or remote request actions.

    uri: https://vault.example.com

    Network access

    medium · line 189

    The documentation includes network, browsing, or remote request actions.

    config.setAllowedOrigins(List.of("https://app.example.com"));

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score78/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars234,327SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    affaan-m/ECC
    Skill path
    skills/springboot-security/SKILL.md
    Commit
    4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38
    License
    MIT
    Collected
    2026-07-28
    Default branch
    main
    View the original SKILL.md

    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
    @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 @PreAuthorize("hasRole('ADMIN')") or @PreAuthorize("@authz.canEdit(#id)")
    • Deny by default; expose only required scopes
    @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
    // BAD: No validation
    @PostMapping("/users")
    public User createUser(@RequestBody UserDto dto) {
      return userService.create(dto);
    }
    
    // GOOD: Validated DTO
    public 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
    // BAD: String concatenation in native query
    @Query(value = "SELECT * FROM users WHERE name = '" + name + "'", nativeQuery = true)
    
    // 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
    @Bean
    public PasswordEncoder passwordEncoder() {
      return new BCryptPasswordEncoder(12); // cost factor 12
    }
    
    // In service
    public 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
    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
    # BAD: Hardcoded in application.yml
    spring:
      datasource:
        password: mySecretPassword123
    
    # GOOD: Environment variable placeholder
    spring:
      datasource:
        password: ${DB_PASSWORD}
    
    # GOOD: Spring Cloud Vault integration
    spring:
      cloud:
        vault:
          uri: https://vault.example.com
          token: ${VAULT_TOKEN}
    

    Security Headers

    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
    @Bean
    public 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
    // Using Bucket4j for per-endpoint rate limiting
    @Component
    public 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.

    Alternatives

    Compare before choosing