Agent Skills by ALSEL
Anthropic Claudeセキュリティ⭐ リポ 154品質スコア 86/100

springboot-security

Java Spring Bootサービスにおける認証・認可、入力検証、CSRF対策、シークレット管理、HTTPヘッダー設定、レート制限、依存関係のセキュリティに関するSpring Securityのベストプラクティスを提供します。これらの実装により、アプリケーションの堅牢なセキュリティ体制を構築できます。

description の原文を見る

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

SKILL.md 本文

Spring Boot セキュリティレビュー

認証の追加、入力処理、エンドポイント作成、シークレット管理を行う際に使用します。

有効化のタイミング

  • 認証の追加(JWT、OAuth2、セッションベース)
  • 認可の実装(@PreAuthorize、ロールベースアクセス)
  • ユーザー入力の検証(Bean Validation、カスタムバリデータ)
  • CORS、CSRF、セキュリティヘッダーの設定
  • シークレット管理(Vault、環境変数)
  • レート制限またはブルートフォース対策の追加
  • 依存関係のCVE脆弱性スキャン

認証

  • ステートレスなJWTまたは失効リストを備えた不透明トークンを推奨
  • セッションには httpOnlySecureSameSite=Strict クッキーを使用
  • OncePerRequestFilter またはリソースサーバーでトークンを検証
@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);
  }
}

認可

  • メソッドセキュリティを有効化: @EnableMethodSecurity
  • @PreAuthorize("hasRole('ADMIN')") または @PreAuthorize("@authz.canEdit(#id)") を使用
  • デフォルトで拒否し、必要なスコープのみ公開
@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();
  }
}

入力検証

  • コントローラーで @Valid を付与してBean Validationを使用
  • DTOに制約を適用: @NotBlank@Email@Size、カスタムバリデータ
  • レンダリング前にHTMLをホワイトリストでサニタイズ
// 悪い例: 検証なし
@PostMapping("/users")
public User createUser(@RequestBody UserDto dto) {
  return userService.create(dto);
}

// 良い例: 検証済み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インジェクション対策

  • Spring Dataリポジトリまたはパラメータ化クエリを使用
  • ネイティブクエリの場合は :param バインディングを使用し、文字列連結を避ける
// 悪い例: ネイティブクエリでの文字列連結
@Query(value = "SELECT * FROM users WHERE name = '" + name + "'", nativeQuery = true)

// 良い例: パラメータ化ネイティブクエリ
@Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true)
List<User> findByName(@Param("name") String name);

// 良い例: Spring Data派生クエリ(自動パラメータ化)
List<User> findByEmailAndActiveTrue(String email);

パスワードエンコーディング

  • パスワードは常にBCryptまたはArgon2でハッシュ化し、平文を保存しない
  • 手動ハッシング化ではなく PasswordEncoder Beanを使用
@Bean
public PasswordEncoder passwordEncoder() {
  return new BCryptPasswordEncoder(12); // コスト係数12
}

// サービス内
public User register(CreateUserDto dto) {
  String hashedPassword = passwordEncoder.encode(dto.password());
  return userRepository.save(new User(dto.email(), hashedPassword));
}

CSRF対策

  • ブラウザセッションアプリの場合、CSRFを有効なままで、フォーム/ヘッダーにトークンを含める
  • Bearer トークンを使用した純粋なAPIの場合、CSRFを無効にしてステートレス認証に依存
http
  .csrf(csrf -> csrf.disable())
  .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

シークレット管理

  • ソースコードにシークレットを含めない。環境またはVaultから読み込む
  • application.yml をクレデンシャルなしで保つ。プレースホルダーを使用
  • トークンとDBクレデンシャルを定期的にローテーション
# 悪い例: application.yml にハードコード
spring:
  datasource:
    password: mySecretPassword123

# 良い例: 環境変数プレースホルダー
spring:
  datasource:
    password: ${DB_PASSWORD}

# 良い例: Spring Cloud Vault統合
spring:
  cloud:
    vault:
      uri: https://vault.example.com
      token: ${VAULT_TOKEN}

セキュリティヘッダー

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設定

  • CORSをセキュリティフィルタレベルで設定し、コントローラーごとではない
  • 許可されるオリジンを制限。本番環境では * を使用しない
@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;
}

// SecurityFilterChain内:
http.cors(cors -> cors.configurationSource(corsConfigurationSource()));

レート制限

  • Bucket4jまたはゲートウェイレベルの制限を高負荷エンドポイントに適用
  • バースト時にログ記録とアラートを実施。429を再試行ヒント付きで返す
// Bucket4jを使用したエンドポイントごとのレート制限
@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\"}");
    }
  }
}

依存関係セキュリティ

  • OWASP Dependency CheckまたはSnyckをCI内で実行
  • Spring BootとSpring Securityをサポートされているバージョンに保つ
  • 既知のCVEでビルドを失敗させる

ロギングと個人識別情報

  • シークレット、トークン、パスワード、または完全なPANデータをログに記録しない
  • 機密フィールドをマスク。構造化JSONロギングを使用

ファイルアップロード

  • サイズ、コンテンツタイプ、拡張子を検証
  • Webルート外に保存。必要に応じてスキャン

リリース前チェックリスト

  • 認証トークンが正しく検証および期限切れ
  • すべての機密パスに認可ガードがある
  • すべての入力が検証およびサニタイズされている
  • 文字列連結SQLがない
  • CSRF対策がアプリケーションタイプに適切
  • シークレットが外部化され、コミットされていない
  • セキュリティヘッダーが設定されている
  • APIにレート制限がある
  • 依存関係がスキャンおよび最新
  • ログに機密データがない

覚えておいてください: デフォルトで拒否、入力検証、最小権限、セキュア・バイ・コンフィギュレーションを優先。

原文

ナビゲーション

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
loulanyue
リポジトリ
loulanyue/awesome-claude-notes
ライセンス
MIT
最終更新
2026/5/3

Source: https://github.com/loulanyue/awesome-claude-notes / ライセンス: MIT

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: loulanyue · loulanyue/awesome-claude-notes · ライセンス: MIT