Java security
Skill Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack/plugins/devtools-pack/skills/java-security
When to activate: Java security, Spring Security, JWT, OAuth2, SecurityFilterChain, method security, CSRF, CORS, password encodingFrom its SKILL.md
npx -y skills add Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack --skill java-securityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
5.5 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
Java Security Patterns
Spring Security 6 Configuration
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(AbstractHttpConfigurer::disable) // stateless API
.sessionManagement(s -> s.sessionCreationPolicy(STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**", "/actuator/health").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
.exceptionHandling(ex -> ex
.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
.accessDeniedHandler(new BearerTokenAccessDeniedHandler())
)
.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
}
JWT with Nimbus (Spring Security)
@Configuration
public class JwtConfig {
@Value("${app.jwt.secret}")
private String jwtSecret;
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withSecretKey(secretKey()).build();
}
@Bean
public JwtEncoder jwtEncoder() {
return new NimbusJwtEncoder(new ImmutableSecret<>(secretKey()));
}
private SecretKey secretKey() {
return new SecretKeySpec(jwtSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
}
}
@Service
@RequiredArgsConstructor
public class TokenService {
private final JwtEncoder encoder;
public String generateToken(UserDetails user) {
Instant now = Instant.now();
JwtClaimsSet claims = JwtClaimsSet.builder()
.issuer("my-service")
.issuedAt(now)
.expiresAt(now.plus(1, ChronoUnit.HOURS))
.subject(user.getUsername())
.claim("roles", user.getAuthorities().stream()
.map(GrantedAuthority::getAuthority).toList())
.build();
return encoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
}
}
Method-Level Security
@Service
public class DocumentService {
@PreAuthorize("hasRole('ADMIN') or #userId == authentication.name")
public Document getDocument(Long id, String userId) { ... }
@PostAuthorize("returnObject.ownerId == authentication.name")
public Document findById(Long id) { ... }
@PreAuthorize("hasAuthority('DOCUMENT_WRITE')")
public Document create(CreateDocumentRequest request) { ... }
@Secured("ROLE_ADMIN")
public void deleteDocument(Long id) { ... }
}
CORS Configuration
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("https://app.example.com"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
config.setAllowedHeaders(List.of("Authorization", "Content-Type"));
config.setAllowCredentials(true);
config.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/api/**", config);
return source;
}
Input Validation & SQL Injection Prevention
// Always use parameterized queries
@Query("SELECT u FROM User u WHERE u.email = :email")
Optional<User> findByEmail(@Param("email") String email);
// Never concatenate user input
// BAD: "SELECT * FROM users WHERE name = '" + name + "'"
// GOOD: jdbcTemplate.queryForObject("SELECT * FROM users WHERE name = ?", User.class, name)
// Validate at boundary
@PostMapping("/users")
public UserResponse create(@Valid @RequestBody CreateUserRequest request) { ... }
public record CreateUserRequest(
@NotBlank @Size(max = 100) String name,
@NotBlank @Email String email,
@Pattern(regexp = "^(?=.*[A-Z])(?=.*\\d).{8,}$") String password
) {}
Secrets Management
// Never hardcode secrets — read from environment
@Value("${app.jwt.secret:#{null}}")
private String jwtSecret;
@PostConstruct
public void validateSecrets() {
if (jwtSecret == null || jwtSecret.length() < 32) {
throw new IllegalStateException("JWT secret must be at least 32 characters");
}
}
// Use Spring Cloud Vault or AWS Secrets Manager in production
@Configuration
@EnableVaultConfiguration
public class VaultConfig extends AbstractVaultConfiguration {
@Override
public VaultEndpoint vaultEndpoint() {
return VaultEndpoint.from(URI.create(System.getenv("VAULT_ADDR")));
}
}
Key Rules
BCryptPasswordEncoder(12)— strength 12 is the minimum for production; never store plain or MD5 passwords- Disable CSRF only for stateless REST APIs; always enable for session-based apps
@PreAuthorizewith SpEL is preferred over role checks in business logic- Never log passwords, tokens, or PII — use structured logging with explicit field exclusions
- Validate all user input at the controller boundary with
@Valid— never trust raw request data
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 1 of the 12 instructions most security skills give in ~1.1k tokens
Counted across 648 of the 828 authors here whose files we hold, read 2026-08-07
- Parameterize all database querieshere, and in 68 of 648, across 51 files
- Hash passwords using bcrypt, scrypt, or argon2in 49 of 648, across 36 files
- Apply rate limiting to authentication endpointsin 48 of 648, across 24 files
- Configure security headersin 35 of 648, across 19 files
- Validate all inputsin 32 of 648, across 24 files
- Validate all external input at the system boundaryin 29 of 648, across 19 files
- Run containers as a non-root userin 28 of 648, across 15 files
- Use httponly secure samesite cookies for sessionsin 26 of 648, across 15 files
- Run dependency audits before every releasein 21 of 648, across 10 files
- Encode output to prevent cross-site scriptingin 21 of 648, across 11 files
- Copy dependencies before source codein 20 of 648, across 9 files
- Store secrets in environment variablesin 20 of 648, across 18 files
Said here and by no other author read
- disable csrf for stateless apis
- enable csrf for session-based apps
- use preauthorize with spel
- validate jwt secret length in postconstruct
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.