
Spring Boot Security
FreeBest practices for securing Spring Boot applications.
Free · Opens the source repo
What Spring Boot Security does
Spring Boot Security is a skill designed for developers working with Java Spring Boot who need guidance on implementing robust security measures. This skill focuses on best practices for authentication, authorization, input validation, and more, ensuring that applications are secure from common vulnerabilities. It provides clear instructions on how to handle authentication using JWT, OAuth2, or session-based methods, and emphasizes the importance of using secure cookies and validating tokens properly.
In addition to authentication, the skill covers authorization strategies, including method-level security with annotations like @PreAuthorize. Developers will learn how to restrict access based on roles and ensure that only necessary scopes are exposed. The skill also addresses input validation, encouraging the use of Bean Validation and custom validators to prevent issues such as SQL injection and cross-site scripting (XSS).
Security headers and CORS configuration are also part of the guidance provided, helping developers to set up their applications to mitigate threats from various sources. The skill emphasizes the importance of managing secrets properly, suggesting that sensitive information should never be hardcoded in the source code, but instead loaded from environment variables or secure vaults. Overall, this skill is an essential resource for any developer looking to enhance the security of their Spring Boot applications.
When to use it
Use this skill when starting a new Spring Boot project or when enhancing the security of an existing application.
When not to use it
This skill may not be suitable for projects that do not require complex security measures or for developers who are already well-versed in Spring Security.
What you can build with it
Implementing JWT Authentication
Use this skill to set up JWT authentication in your Spring Boot application, ensuring secure and stateless sessions.
Configuring CORS for APIs
Utilize the guidance on CORS configuration to restrict access to your API endpoints based on allowed origins.
Validating User Input
Apply the input validation techniques from this skill to prevent common vulnerabilities like XSS and SQL injection.
How to install Spring Boot Security
View source1. Install with the skills CLI
npx skills add affaan-m/ecc/springboot-security --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by affaan-mRevisió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=Strictpara sesiones - Validar tokens con
OncePerRequestFiltero 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
@Validen 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.ymllibre 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.
Frequently asked questions about Spring Boot Security
Similar skills
Python PyPI Package Builder
Streamline the process of creating and publishing Python packages.
Minecraft Plugin Development
Streamline your Minecraft server plugin creation.
MCP Server Builder
Easily build .NET MCP servers with the latest standards.
CommunityToolkit.Mvvm Messenger
Decoupled communication for ViewModels in .NET applications.
MVVM Toolkit DI
Streamline ViewModel integration with Dependency Injection in .NET.
MCP Apps Builder
Essential guidelines for MCP server development.
