Source profileQuality 74/100

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

springboot-security

Buenas prácticas de Spring Security para autenticación/autorización, validación, CSRF, secretos, cabeceras, limitación de velocidad y seguridad de dependencias en servicios Java Spring Boot.

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

Usar al agregar autenticación, manejar entradas, crear endpoints o trabajar con secretos.

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 "docs/es/skills/springboot-security"
    Safe inspection promptEditorial

    Inspect the Agent Skill "springboot-security" from https://github.com/affaan-m/ECC/blob/4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38/docs/es/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

      Cuándo Activar

      Agregar autenticación (JWT, OAuth2, basada en sesión)

      Agregar autenticación (JWT, OAuth2, basada en sesión)Implementar autorización (@PreAuthorize, control de acceso basado en roles)Validar entrada de usuario (Bean Validation, validadores personalizados)
    2. 02

      Autenticación

      Preferir JWT sin estado o tokens opacos con lista de revocación

      Preferir JWT sin estado o tokens opacos con lista de revocaciónUsar cookies httpOnly, Secure, SameSite=Strict para sesionesValidar tokens con OncePerRequestFilter o resource server
    3. 03

      Autorización

      Habilitar seguridad de métodos: @EnableMethodSecurity

      Habilitar seguridad de métodos: @EnableMethodSecurityUsar @PreAuthorize("hasRole('ADMIN')") o @PreAuthorize("@authz.canEdit(id)")Denegar por defecto; exponer solo los scopes requeridos
    4. 04

      Validación de Entrada

      Usar Bean Validation con @Valid en controllers

      Usar Bean Validation con @Valid en controllersAplicar restricciones en DTOs: @NotBlank, @Email, @Size, validadores personalizadosSanitizar cualquier HTML con lista blanca antes de renderizar
    5. 05

      Prevención de Inyección SQL

      Usar repositorios de Spring Data o consultas parametrizadas

      Usar repositorios de Spring Data o consultas parametrizadasPara consultas nativas, usar bindings :param; nunca concatenar cadenas- Usar repositorios de Spring Data o consultas parametrizadas - Para consultas nativas, usar bindings :param; nunca concatenar cadenas

    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 score74/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
    docs/es/skills/springboot-security/SKILL.md
    Commit
    4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38
    License
    MIT
    Collected
    2026-07-28
    Default branch
    main
    View the original SKILL.md

    Revisión de Seguridad Spring Boot

    Usar al agregar autenticación, manejar entradas, crear endpoints o trabajar con secretos.

    Cuándo Activar

    • Agregar autenticación (JWT, OAuth2, basada en sesión)
    • Implementar autorización (@PreAuthorize, control de acceso basado en roles)
    • Validar entrada de usuario (Bean Validation, validadores personalizados)
    • Configurar CORS, CSRF o cabeceras de seguridad
    • Gestionar secretos (Vault, variables de entorno)
    • Agregar limitación de velocidad o protección contra fuerza bruta
    • Escanear dependencias por CVEs

    Autenticación

    • Preferir JWT sin estado o tokens opacos con lista de revocación
    • Usar cookies httpOnly, Secure, SameSite=Strict para sesiones
    • Validar tokens con OncePerRequestFilter o 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);
      }
    }
    

    Autorización

    • Habilitar seguridad de métodos: @EnableMethodSecurity
    • Usar @PreAuthorize("hasRole('ADMIN')") o @PreAuthorize("@authz.canEdit(#id)")
    • Denegar por defecto; exponer solo los scopes requeridos
    @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();
      }
    }
    

    Validación de Entrada

    • Usar Bean Validation con @Valid en controllers
    • Aplicar restricciones en DTOs: @NotBlank, @Email, @Size, validadores personalizados
    • Sanitizar cualquier HTML con lista blanca antes de renderizar
    // MAL: Sin validación
    @PostMapping("/users")
    public User createUser(@RequestBody UserDto dto) {
      return userService.create(dto);
    }
    
    // BIEN: DTO validado
    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));
    }
    

    Prevención de Inyección SQL

    • Usar repositorios de Spring Data o consultas parametrizadas
    • Para consultas nativas, usar bindings :param; nunca concatenar cadenas
    // MAL: Concatenación de cadenas en consulta nativa
    @Query(value = "SELECT * FROM users WHERE name = '" + name + "'", nativeQuery = true)
    
    // BIEN: Consulta nativa parametrizada
    @Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true)
    List<User> findByName(@Param("name") String name);
    
    // BIEN: Consulta derivada de Spring Data (auto-parametrizada)
    List<User> findByEmailAndActiveTrue(String email);
    

    Codificación de Contraseñas

    • Siempre hashear contraseñas con BCrypt o Argon2 — nunca almacenar en texto plano
    • Usar el bean PasswordEncoder, no hashing manual
    @Bean
    public PasswordEncoder passwordEncoder() {
      return new BCryptPasswordEncoder(12); // factor de costo 12
    }
    
    // En el servicio
    public User register(CreateUserDto dto) {
      String hashedPassword = passwordEncoder.encode(dto.password());
      return userRepository.save(new User(dto.email(), hashedPassword));
    }
    

    Protección CSRF

    • Para aplicaciones de sesión de navegador, mantener CSRF habilitado; incluir token en formularios/cabeceras
    • Para APIs puras con tokens Bearer, deshabilitar CSRF y depender de autenticación sin estado
    http
      .csrf(csrf -> csrf.disable())
      .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
    

    Gestión de Secretos

    • Sin secretos en el código fuente; cargar desde entorno o vault
    • Mantener application.yml libre de credenciales; usar marcadores de posición
    • Rotar tokens y credenciales de base de datos regularmente
    # MAL: Hardcodeado en application.yml
    spring:
      datasource:
        password: mySecretPassword123
    
    # BIEN: Marcador de variable de entorno
    spring:
      datasource:
        password: ${DB_PASSWORD}
    
    # BIEN: Integración con Spring Cloud Vault
    spring:
      cloud:
        vault:
          uri: https://vault.example.com
          token: ${VAULT_TOKEN}
    

    Cabeceras de Seguridad

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

    Configuración de CORS

    • Configurar CORS a nivel del filtro de seguridad, no por controller
    • Restringir orígenes permitidos — nunca usar * en producción
    @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;
    }
    
    // En SecurityFilterChain:
    http.cors(cors -> cors.configurationSource(corsConfigurationSource()));
    

    Limitación de Velocidad

    • Aplicar Bucket4j o límites a nivel de gateway en endpoints costosos
    • Registrar y alertar sobre ráfagas; retornar 429 con hints de reintento
    // Usar Bucket4j para limitación de velocidad por endpoint
    @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\"}");
        }
      }
    }
    

    Seguridad de Dependencias

    • Ejecutar OWASP Dependency Check / Snyk en CI
    • Mantener Spring Boot y Spring Security en versiones soportadas
    • Fallar builds ante CVEs conocidos

    Logging y PII

    • Nunca registrar secretos, tokens, contraseñas ni datos PAN completos
    • Redactar campos sensibles; usar logging JSON estructurado

    Subida de Archivos

    • Validar tamaño, tipo de contenido y extensión
    • Almacenar fuera del web root; escanear si es requerido

    Lista de Verificación Antes del Lanzamiento

    • Tokens de autenticación validados y con expiración correcta
    • Guardias de autorización en cada ruta sensible
    • Todas las entradas validadas y sanitizadas
    • Sin SQL concatenado con cadenas
    • Postura CSRF correcta para el tipo de aplicación
    • Secretos externalizados; ninguno con commit
    • Cabeceras de seguridad configuradas
    • Limitación de velocidad en APIs
    • Dependencias escaneadas y actualizadas
    • Logs libres de datos sensibles

    Recuerda: Denegar por defecto, validar entradas, privilegio mínimo y seguro por configuración primero.

    Alternatives

    Compare before choosing