agentsclimarketplace

Spring boot security scan

Skill Dolphinllc/claude-security-skills/skills/defensive/web/spring-boot-security-scan

Defensive security skills for Claude Code and the Claude Agent SDK — web applications and generative AI systems.

Install
npx -y skills add Dolphinllc/claude-security-skills --skill spring-boot-security-scan

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 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.

What its author says it does

Copied from the file, not written here

Defensive security scan for Spring Boot applications using Spring Security. Detects permitAll on sensitive routes, disabled CSRF on stateful endpoints, wildcard CORS with credentials, missing @PreAuthorize, JdbcTemplate string concatenation, Jackson default typing, exposed actuators, and weak BCrypt strength. Invoke when the user asks to "review", "audit", or "scan" a Spring Boot project.

SKILL.md

5.2 KB, as published. Nobody here has run it

Spring Boot Security Scan

Defensive scan for Spring Boot 3.x with Spring Security 6.x. Reports findings using the shared scoring schema.

Scope

  • *Application.java and @Configuration classes
  • SecurityFilterChain beans / WebSecurityConfigurerAdapter (legacy)
  • @RestController / @Controller classes
  • application.{properties,yml}
  • Repositories / DAOs using JdbcTemplate, EntityManager, native queries

Procedure

  1. Locate every SecurityFilterChain bean and read the request-matcher rules in order — first match wins.
  2. Walk controller methods for @PreAuthorize / @Secured / endpoint-level rules.
  3. Inspect data-access layer for native queries built by string concat.
  4. Inspect application.{properties,yml} for secrets and actuator exposure.

Rules

IDSeverityDetectionFix
SB-SEC-001criticalSecurityFilterChain with .anyRequest().permitAll().anyRequest().authenticated() (whitelist exceptions explicitly)
SB-SEC-002high.csrf(csrf -> csrf.disable()) on a stateful (cookie-session) appKeep CSRF enabled; disable only for stateless JWT APIs and document why
SB-SEC-003highCustom matcher allows /actuator/** or /admin/** without role checkRequire hasRole("ADMIN")
SB-SEC-004mediumhttpBasic() enabled together with form login on the same chain (auth confusion)Pick one mechanism per chain
SB-CORS-001high@CrossOrigin(origins = "*") with allowCredentials = "true"Pin origins via CorsConfigurationSource allowlist
SB-CTRL-001high@RestController method performing mutation lacks @PreAuthorize and the chain's matcher only requires authenticated()Add @PreAuthorize("hasRole('...')") or tighten chain
SB-CTRL-002medium@RequestMapping without method = on mutating endpoints (accepts GET)Use @PostMapping / @PutMapping etc.
SB-VALID-001high@RequestBody parameter not annotated with @Valid / @ValidatedAdd @Valid; declare constraints on DTO
SB-SQL-001criticaljdbcTemplate.query("... " + var + " ...", ...) or String.format into SQLUse ? placeholders + args array, or NamedParameterJdbcTemplate
SB-SQL-002high@Query(value = "SELECT ... WHERE col = '" + ... ) (concat) — or nativeQuery=true with String.formatBind via :param
SB-JACKSON-001criticalObjectMapper.activateDefaultTyping(...) / enableDefaultTyping() enabled on input deserializationRemove default typing; use @JsonTypeInfo allowlist
SB-CFG-001criticalapplication.{properties,yml} contains literal credentials (spring.datasource.password=..., API keys)Externalize via env / Vault; rotate
SB-ACT-001highmanagement.endpoints.web.exposure.include=* without securing actuator chainEnumerate exposed endpoints; require ACTUATOR role
SB-ACT-002medium/actuator/heapdump, /actuator/env, /actuator/configprops exposedDisable or restrict to internal network
SB-PWD-001highBCryptPasswordEncoder() default strength used (10) for high-value accounts — acceptable but consider 12Use BCryptPasswordEncoder(12) for admin tier
SB-PWD-002criticalNoOpPasswordEncoder / plaintext comparisonUse BCryptPasswordEncoder or Argon2PasswordEncoder
SB-LOG-001mediumlog.info("user={}", user) where user toString includes hash/PIIOverride toString to redact or log id only

Wrong vs. right

SB-SEC-001 (permitAll)

// ❌ Everything is open
http
  .authorizeHttpRequests(a -> a.anyRequest().permitAll())
  .build();
// ✅ Default-deny + explicit whitelist
http
  .authorizeHttpRequests(a -> a
    .requestMatchers("/", "/health", "/login").permitAll()
    .requestMatchers("/admin/**").hasRole("ADMIN")
    .anyRequest().authenticated())
  .build();

SB-SQL-001 (string concat)

// ❌
jdbcTemplate.query("SELECT * FROM users WHERE email = '" + email + "'", rowMapper);
// ✅
jdbcTemplate.query("SELECT * FROM users WHERE email = ?", rowMapper, email);

SB-JACKSON-001 (default typing)

// ❌ Polymorphic deserialization → RCE gadget chains
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance);
// ✅ Allowlist subtypes via annotations
@JsonTypeInfo(use = Id.NAME, property = "type")
@JsonSubTypes({ @Type(Cat.class, name = "cat"), @Type(Dog.class, name = "dog") })
public abstract class Pet { }

References

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.