Spring Securityは、HTTPレスポンスにセキュリティヘッダーを自動的に付与することで、XSS攻撃、クリックジャッキング、MIMEスニッフィングなどの一般的なWeb攻撃からアプリケーションを保護します。本記事では、headers()メソッドを使用したセキュリティヘッダーの設定方法と、各ヘッダーの効果について詳しく解説します。
実行環境と前提条件#
本記事の内容を実践するにあたり、以下の環境を前提としています。
| 項目 |
バージョン・要件 |
| Java |
17以上 |
| Spring Boot |
3.4.x |
| Spring Security |
6.4.x |
| ビルドツール |
Maven または Gradle |
| IDE |
VS Code または IntelliJ IDEA |
事前に以下の知識があると理解がスムーズです。
- Spring Securityの基本的な設定方法
- SecurityFilterChainの概念
- HTTPヘッダーの基礎知識
Spring Securityのデフォルトセキュリティヘッダー#
Spring Securityは、特別な設定をしなくても以下のセキュリティヘッダーをデフォルトで付与します。
デフォルトで付与されるヘッダー#
1
2
3
4
5
6
7
|
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
X-XSS-Protection: 0
|
各ヘッダーの役割を確認しましょう。
| ヘッダー |
効果 |
| Cache-Control, Pragma, Expires |
認証済みコンテンツのキャッシュを防止 |
| X-Content-Type-Options |
MIMEスニッフィング攻撃を防止 |
| Strict-Transport-Security |
HTTPS通信を強制(HTTPSリクエスト時のみ付与) |
| X-Frame-Options |
クリックジャッキング攻撃を防止 |
| X-XSS-Protection |
非推奨のXSSフィルターを無効化 |
デフォルト設定の確認#
Spring Bootプロジェクトでは、spring-boot-starter-securityを追加するだけでこれらのヘッダーが有効になります。
1
2
3
4
|
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
|
cURLコマンドでレスポンスヘッダーを確認できます。
1
|
curl -I http://localhost:8080/api/resource
|
Spring Securityでは、SecurityFilterChainの設定内でheaders()メソッドを使用してセキュリティヘッダーをカスタマイズします。
基本的な設定構造#
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
// ヘッダー設定をここに記述
);
return http.build();
}
}
|
設定フローの概要#
flowchart TD
A[HTTPリクエスト] --> B[SecurityFilterChain]
B --> C[HeaderWriterFilter]
C --> D{headers設定を適用}
D --> E[X-Frame-Options]
D --> F[X-Content-Type-Options]
D --> G[Strict-Transport-Security]
D --> H[Content-Security-Policy]
E & F & G & H --> I[HTTPレスポンス]X-Frame-Optionsの設定(クリックジャッキング対策)#
X-Frame-Optionsヘッダーは、ページが<iframe>、<frame>、<embed>、<object>要素内に表示されることを制御し、クリックジャッキング攻撃を防止します。
クリックジャッキング攻撃の仕組み#
sequenceDiagram
participant User as ユーザー
participant Attacker as 攻撃者サイト
participant Target as 標的サイト
User->>Attacker: 攻撃者サイトにアクセス
Attacker->>User: 透明なiframeで標的サイトを重ねて表示
Note over User: ユーザーには攻撃者サイトの<br/>コンテンツのみが見える
User->>Attacker: ボタンをクリック(意図しない操作)
Attacker->>Target: 実際には標的サイトへの<br/>リクエストが送信されるX-Frame-Optionsの設定オプション#
| 値 |
効果 |
| DENY |
すべてのフレーム内表示を拒否(デフォルト) |
| SAMEORIGIN |
同一オリジンからのフレーム内表示のみ許可 |
| 無効化 |
フレーム内表示の制限なし(非推奨) |
設定例:DENYの場合(デフォルト)#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.headers(headers -> headers
.frameOptions(frameOptions -> frameOptions
.deny()
)
);
return http.build();
}
}
|
レスポンスヘッダー:
設定例:SAMEORIGINの場合#
同一オリジンのページからのiframe埋め込みを許可する場合は、sameOrigin()を使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.headers(headers -> headers
.frameOptions(frameOptions -> frameOptions
.sameOrigin()
)
);
return http.build();
}
}
|
レスポンスヘッダー:
1
|
X-Frame-Options: SAMEORIGIN
|
X-Frame-Optionsを無効化する場合#
Content-Security-PolicyのFrame-ancestorsディレクティブを使用する場合など、X-Frame-Optionsを無効化したいケースがあります。
1
2
3
4
5
6
7
8
9
10
|
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.frameOptions(frameOptions -> frameOptions
.disable()
)
);
return http.build();
}
|
X-Content-Type-Optionsの設定(MIMEスニッフィング対策)#
X-Content-Type-Optionsヘッダーは、ブラウザによるMIMEタイプの推測(スニッフィング)を防止し、Content-Typeヘッダーで指定されたタイプのみを信頼するよう指示します。
MIMEスニッフィング攻撃のリスク#
MIMEスニッフィングが有効な場合、攻撃者が悪意のあるスクリプトを画像やテキストファイルに偽装してアップロードし、ブラウザがそれをJavaScriptとして実行してしまう可能性があります。
flowchart LR
A[攻撃者] -->|悪意のあるJSを<br/>画像として偽装| B[サーバー]
B -->|Content-Type: image/png| C[ブラウザ]
C -->|MIMEスニッフィング| D{コンテンツを解析}
D -->|JSとして検出| E[スクリプト実行]
E --> F[XSS攻撃成功]設定例#
Spring Securityはデフォルトでnosniffを設定しますが、明示的に設定する場合は以下のようにします。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.contentTypeOptions(contentTypeOptions -> {})
);
return http.build();
}
}
|
レスポンスヘッダー:
1
|
X-Content-Type-Options: nosniff
|
無効化する場合(非推奨)#
1
2
3
4
5
6
7
8
9
10
|
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.contentTypeOptions(contentTypeOptions -> contentTypeOptions
.disable()
)
);
return http.build();
}
|
Strict-Transport-Security(HSTS)の設定#
Strict-Transport-Security(HSTS)ヘッダーは、ブラウザに対してHTTPS通信を強制し、中間者攻撃のリスクを軽減します。
HSTSが防ぐ攻撃#
sequenceDiagram
participant User as ユーザー
participant Browser as ブラウザ
participant Attacker as 攻撃者
participant Server as サーバー
Note over User,Browser: HSTSなしの場合
User->>Browser: http://example.com
Attacker->>Browser: HTTPリクエストを傍受<br/>改ざんしたレスポンスを返却
Browser->>User: 攻撃者のコンテンツ表示
Note over User,Browser: HSTSありの場合
User->>Browser: http://example.com
Browser->>Browser: HSTSポリシーを確認<br/>HTTPSに自動変換
Browser->>Server: https://example.com
Server->>Browser: 正規のレスポンスHSTSの設定オプション#
| オプション |
説明 |
デフォルト値 |
| maxAgeInSeconds |
HSTSポリシーの有効期間(秒) |
31536000(1年) |
| includeSubDomains |
サブドメインにも適用するか |
true |
| preload |
ブラウザのプリロードリストに登録する意図を示す |
false |
設定例:カスタムHSTS設定#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.httpStrictTransportSecurity(hsts -> hsts
.maxAgeInSeconds(63072000) // 2年
.includeSubDomains(true)
.preload(true)
)
);
return http.build();
}
}
|
レスポンスヘッダー(HTTPSリクエスト時のみ付与):
1
|
Strict-Transport-Security: max-age=63072000 ; includeSubDomains ; preload
|
HSTSプリロードについて#
preloadオプションを有効にした場合、hstspreload.orgでサイトを登録することで、主要ブラウザのプリロードリストに追加されます。これにより、初回アクセス時からHTTPS通信が強制されます。
プリロード登録の条件:
- 有効なSSL証明書を持つこと
- HTTPからHTTPSへリダイレクトすること
- すべてのサブドメインがHTTPSであること
max-ageが31536000秒(1年)以上であること
Content-Security-Policy(CSP)の設定#
Content-Security-Policy(CSP)は、XSS攻撃やデータインジェクション攻撃を防ぐための強力なセキュリティ機構です。Spring Securityは、デフォルトではCSPを付与しません。アプリケーションごとに適切なポリシーを設定する必要があります。
CSPの主要ディレクティブ#
| ディレクティブ |
説明 |
| default-src |
他のディレクティブで指定されていないリソースのデフォルト |
| script-src |
JavaScriptの読み込み元 |
| style-src |
CSSの読み込み元 |
| img-src |
画像の読み込み元 |
| connect-src |
fetch、XHR、WebSocketの接続先 |
| frame-ancestors |
当該ページをiframeで埋め込める親ページ |
| form-action |
フォームの送信先 |
| report-uri / report-to |
違反レポートの送信先 |
基本的なCSP設定#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives(
"default-src 'self'; " +
"script-src 'self'; " +
"style-src 'self'; " +
"img-src 'self' data:; " +
"font-src 'self'; " +
"connect-src 'self'; " +
"frame-ancestors 'none'; " +
"form-action 'self'; " +
"base-uri 'self'; " +
"object-src 'none'"
)
)
);
return http.build();
}
}
|
レスポンスヘッダー:
1
|
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self'; object-src 'none'
|
CSPレポートモードの活用#
新しいCSPポリシーを本番環境に適用する前に、Content-Security-Policy-Report-Onlyヘッダーを使用してテストできます。このモードでは、違反を検出してもリソースのブロックは行わず、レポートのみを送信します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives(
"default-src 'self'; " +
"script-src 'self' https://trusted.example.com; " +
"report-uri /csp-report"
)
.reportOnly()
)
);
return http.build();
}
|
レスポンスヘッダー:
1
|
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://trusted.example.com; report-uri /csp-report
|
CSP違反レポートの受信エンドポイント#
CSP違反レポートを受け取るエンドポイントを実装します。
1
2
3
4
5
6
7
8
9
10
11
12
|
@RestController
@RequestMapping("/csp-report")
public class CspReportController {
private static final Logger log = LoggerFactory.getLogger(CspReportController.class);
@PostMapping(consumes = "application/csp-report")
public ResponseEntity<Void> handleCspReport(@RequestBody String report) {
log.warn("CSP Violation Report: {}", report);
return ResponseEntity.ok().build();
}
}
|
CSP違反が発生すると、以下のようなJSONレポートが送信されます。
1
2
3
4
5
6
7
8
9
10
11
|
{
"csp-report": {
"document-uri": "https://example.com/page",
"referrer": "",
"violated-directive": "script-src 'self'",
"effective-directive": "script-src",
"original-policy": "default-src 'self'; script-src 'self'",
"blocked-uri": "https://evil.example.com/malicious.js",
"status-code": 200
}
}
|
Nonceを使用したインラインスクリプトの許可#
インラインスクリプトを安全に許可するために、nonceを使用できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives(
"default-src 'self'; " +
"script-src 'self' 'nonce-{nonce}'"
)
)
);
return http.build();
}
}
|
ThymeleafなどのテンプレートエンジンでCSP nonceを使用する場合は、リクエストごとにnonceを生成し、テンプレートに渡す必要があります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@Component
public class CspNonceFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
String nonce = UUID.randomUUID().toString().replace("-", "");
request.setAttribute("cspNonce", nonce);
response.setHeader("Content-Security-Policy",
"default-src 'self'; script-src 'self' 'nonce-" + nonce + "'");
filterChain.doFilter(request, response);
}
}
|
Referrer-Policyの設定#
Referrer-Policyヘッダーは、リクエスト時にRefererヘッダーにどの程度の情報を含めるかを制御します。Spring Securityはデフォルトではこのヘッダーを付与しません。
Referrer-Policyの値#
| 値 |
説明 |
| no-referrer |
Refererヘッダーを送信しない |
| no-referrer-when-downgrade |
HTTPSからHTTPへの遷移時にRefererを送信しない |
| same-origin |
同一オリジンの場合のみRefererを送信 |
| origin |
オリジン情報のみ送信(パスは含まない) |
| strict-origin |
HTTPSの場合のみオリジン情報を送信 |
| strict-origin-when-cross-origin |
同一オリジンではフルURL、クロスオリジンではオリジンのみ |
設定例#
1
2
3
4
5
6
7
8
9
10
|
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.referrerPolicy(referrer -> referrer
.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
)
);
return http.build();
}
|
レスポンスヘッダー:
1
|
Referrer-Policy: strict-origin-when-cross-origin
|
Permissions-Policyの設定#
Permissions-Policy(旧Feature-Policy)は、ブラウザの機能(カメラ、マイク、位置情報など)へのアクセスを制御します。
設定例#
1
2
3
4
5
6
7
8
9
10
|
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.permissionsPolicy(permissions -> permissions
.policy("camera=(), microphone=(), geolocation=(self), fullscreen=(self)")
)
);
return http.build();
}
|
レスポンスヘッダー:
1
|
Permissions-Policy: camera=(), microphone=(), geolocation=(self), fullscreen=(self)
|
包括的なセキュリティヘッダー設定の実装例#
実際のプロジェクトで使用できる、包括的なセキュリティヘッダー設定の例を示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/csp-report").permitAll()
.anyRequest().authenticated()
)
.headers(headers -> headers
// デフォルト設定を明示的に無効化し、必要なものだけ設定
.defaultsDisabled()
// Cache-Control(認証済みコンテンツのキャッシュ防止)
.cacheControl(cache -> {})
// X-Content-Type-Options(MIMEスニッフィング防止)
.contentTypeOptions(contentType -> {})
// X-Frame-Options(クリックジャッキング防止)
.frameOptions(frame -> frame.deny())
// Strict-Transport-Security(HTTPS強制)
.httpStrictTransportSecurity(hsts -> hsts
.maxAgeInSeconds(31536000)
.includeSubDomains(true)
.preload(true)
)
// Content-Security-Policy(XSS・インジェクション防止)
.contentSecurityPolicy(csp -> csp
.policyDirectives(
"default-src 'self'; " +
"script-src 'self'; " +
"style-src 'self' 'unsafe-inline'; " +
"img-src 'self' data: https:; " +
"font-src 'self'; " +
"connect-src 'self'; " +
"frame-ancestors 'none'; " +
"form-action 'self'; " +
"base-uri 'self'; " +
"object-src 'none'; " +
"report-uri /csp-report"
)
)
// Referrer-Policy(リファラー情報の制御)
.referrerPolicy(referrer -> referrer
.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
)
// Permissions-Policy(ブラウザ機能の制限)
.permissionsPolicy(permissions -> permissions
.policy("camera=(), microphone=(), geolocation=(self)")
)
);
return http.build();
}
}
|
設定のインポート#
上記の設定で必要なインポート文は以下のとおりです。
1
2
3
4
5
6
|
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
|
静的リソースへのヘッダー設定#
静的リソース(CSS、JavaScript、画像など)に対しては、キャッシュを有効にしつつセキュリティヘッダーを適用する必要があります。
静的リソース用の設定#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
@Order(1)
public SecurityFilterChain staticResourcesFilterChain(HttpSecurity http) throws Exception {
http
.securityMatcher("/static/**", "/css/**", "/js/**", "/images/**")
.authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
.headers(headers -> headers
// 静的リソースはキャッシュを有効化
.cacheControl(cache -> cache.disable())
.contentTypeOptions(contentType -> {})
.frameOptions(frame -> frame.deny())
);
return http.build();
}
@Bean
@Order(2)
public SecurityFilterChain defaultFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
.headers(headers -> headers
// 動的コンテンツはキャッシュを無効化
.cacheControl(cache -> {})
.contentTypeOptions(contentType -> {})
.frameOptions(frame -> frame.deny())
);
return http.build();
}
}
|
カスタムヘッダーの追加#
Spring Securityが提供するヘッダー以外に、独自のセキュリティヘッダーを追加することも可能です。
1
2
3
4
5
6
7
8
9
|
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header", "custom-value"))
.addHeaderWriter(new StaticHeadersWriter("X-Powered-By", ""))
);
return http.build();
}
|
条件付きでヘッダーを追加する場合#
特定のURLパターンにのみヘッダーを追加する場合は、DelegatingRequestMatcherHeaderWriterを使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
RequestMatcher adminMatcher = new AntPathRequestMatcher("/admin/**");
DelegatingRequestMatcherHeaderWriter headerWriter =
new DelegatingRequestMatcherHeaderWriter(
adminMatcher,
new StaticHeadersWriter("X-Admin-Area", "true")
);
http
.headers(headers -> headers
.addHeaderWriter(headerWriter)
);
return http.build();
}
|
セキュリティヘッダーのテスト#
設定したセキュリティヘッダーが正しく付与されているかをテストする方法を紹介します。
MockMvcを使用したテスト#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
@SpringBootTest
@AutoConfigureMockMvc
class SecurityHeadersTest {
@Autowired
private MockMvc mockMvc;
@Test
@WithMockUser
void shouldIncludeSecurityHeaders() throws Exception {
mockMvc.perform(get("/api/resource"))
.andExpect(status().isOk())
.andExpect(header().string("X-Content-Type-Options", "nosniff"))
.andExpect(header().string("X-Frame-Options", "DENY"))
.andExpect(header().exists("Content-Security-Policy"))
.andExpect(header().string("Referrer-Policy", "strict-origin-when-cross-origin"));
}
@Test
@WithMockUser
void shouldIncludeHstsHeaderOnHttps() throws Exception {
mockMvc.perform(get("/api/resource")
.secure(true))
.andExpect(status().isOk())
.andExpect(header().exists("Strict-Transport-Security"));
}
@Test
void shouldIncludeCspHeader() throws Exception {
mockMvc.perform(get("/api/public/resource"))
.andExpect(header().string("Content-Security-Policy",
containsString("default-src 'self'")));
}
}
|
ブラウザ開発者ツールでの確認#
ブラウザの開発者ツール(F12)のNetworkタブで、レスポンスヘッダーを確認できます。正しく設定されている場合、Response Headersセクションにセキュリティヘッダーが表示されます。
外部ツールを使用した検証#
以下のオンラインツールでセキュリティヘッダーの設定を検証できます。
トラブルシューティング#
よくある問題と解決策#
| 問題 |
原因 |
解決策 |
| CSPでインラインスクリプトがブロックされる |
script-src 'self'のみの設定 |
nonceまたはハッシュを使用するか、'unsafe-inline'を追加(非推奨) |
| 外部CDNのリソースが読み込めない |
CSPで許可されていない |
該当するディレクティブにCDNのドメインを追加 |
| iframeが表示されない |
X-Frame-Options: DENY |
sameOrigin()に変更するか、CSPのframe-ancestorsを設定 |
| HSTSヘッダーが付与されない |
HTTPでアクセスしている |
HTTPSでアクセスする |
デバッグ方法#
セキュリティヘッダーの問題をデバッグするには、Spring Securityのログレベルを上げます。
1
2
3
4
|
logging:
level:
org.springframework.security: DEBUG
org.springframework.security.web.header: TRACE
|
まとめ#
Spring Securityのセキュリティヘッダー設定について解説しました。重要なポイントをまとめます。
- Spring Securityはデフォルトで基本的なセキュリティヘッダーを付与する
headers()メソッドを使用してヘッダーをカスタマイズできる
- X-Frame-Optionsはクリックジャッキング攻撃を防止する
- X-Content-Type-OptionsはMIMEスニッフィング攻撃を防止する
- HSTSはHTTPS通信を強制し、中間者攻撃を防止する
- CSPはXSS攻撃やデータインジェクション攻撃に対する強力な防御機構
- CSPレポートモードを活用して段階的にポリシーを導入できる
- テストを作成してセキュリティヘッダーの設定を検証する
これらのセキュリティヘッダーを適切に設定することで、Webアプリケーションの防御力を大幅に向上させることができます。
参考リンク#