1. Default Security Headers
- Spring Security는 응답 헤더에 보안에 관련된 헤더를 자동으로 추가해 줌
기본 보안 응답 헤더
헤더 이름 | 값 | 설명 | 목적 |
Cache-Control (브라우저 캐시 제어) |
no-cache, no-store, max-age=0, must-revalidate |
브라우저 캐시 차단 (해당 페이지 및 리소스 캐시 ❌) |
사용자 민감정보 노출 방지 (뒤로가기 시 민감정보가 남아있음) |
Pragma | no-cache | HTTP/1.0 캐시 비활성화 | HTTP1.0 시대의 캐시 헤더 (버전 호환성을 위해 추가됨) |
Expires | 0 | 만료일이 과거로 설정되어 캐시 방지 | HTTP1.0 시대의 캐시 헤더 (버전 호환성을 위해 추가됨) |
X-Content-Type-Options | nosniff | 브라우저가 MIME 타입 추측 못하게 차단 | XSS 방지 |
Strict-Transport-Security (HSTS) |
max-age=31536000; includeSubDomains |
HTTPS 요청 강제 (단, HTTPS 응답일 때만 삽입됨) |
Man-in-the-middle 방지 |
X-Frame-Options | DENY | 해당 웹 페이지의 iframe 삽입 허용 금지 |
클릭재킹 방지 |
X-XSS-Protection |
0
|
브라우저의 XSS 보호 기능 비활성화 |
예시) Http Response Header
더보기
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
커스터마이징
- Spring Security는 사용자 정의 헤더를 우선시함
설정) 브라우저 캐시 헤더 - 정적 리소스 캐시 허용
더보기
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**", "/js/**")
.addResourceLocations("classpath:/static/css/", "classpath:/static/js/")
.setCacheControl(CacheControl.maxAge(30, TimeUnit.DAYS).cachePublic());
}
}
- HttpSecurity의 headers.cacheControl은 전역 설정이므로 경로별 설정은 위와 같이 설정함
설정) X-Frame-Options - 같은 도메인에 한하여 iframe 허용
더보기
http
.headers(headers -> headers
.frameOptions(frame -> frame
.sameOrigin() // 같은 도메인 내에선 iframe 허용
)
);
- 신뢰된 환경에서 iframe 필요할 때 완화하여 사용할 수 있음
2. Content Security Policy
- 브라우저에게 리소스 로딩을 제한하라는 명령을 내리는 보안 정책 (지정된 출처 외 리소스 로딩 차단)
- 콘텐츠 주입 공격을 브라우저 단에서 차단해줌 (XSS, clickjacking 등)
Header
항목 | Content-Security-Policy |
Content-Security-Policy-Report-Only
|
기능 | 정책을 강제 적용 |
정책을 모니터링만 하고 적용하지 않음
|
위반 리소스 처리 | 로딩 차단 | 로딩 허용 |
사용 목적 | 실제 보안 적용 목적 |
사전 테스트 및 정책 점검 목적
|
브라우저 동작 차이 | 정책을 위반하면 리소스를 막음 |
정책을 위반해도 리소스를 그대로 로딩함
|
예시) Content-Security-Policy
더보기
Content-Security-Policy: script-src https://trustedscripts.example.com
Content-Security-Policy: script-src https://trustedscripts.example.com; report-uri /csp-report-endpoint/
- script-src : 스크립트를 로드할 수 있는 화이트리스트를 지정하는 지시어
- report-url : 보안정책 위반을 보고할 uri를 지정하는 지시어
예시) Content-Security-Policy-Report-Only
더보기
Content-Security-Policy-Report-Only: script-src 'self' https://trustedscripts.example.com; report-uri /csp-report-endpoint/
커스터마이징
설정) script-scr, report-src 추가
더보기
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
.reportOnly()
)
);
return http.build();
}
3. Referrer Policy
Referrer 헤더
- 브라우저가 요청 시, 이 요청이 어디로부터 왔는지 알려주는 헤더
- 보안 목적 (개인정보 보호)
Referrer Policy
- Referrer 헤더의 가시성에 대한 제어 규칙을 정의함 (Referrer 헤더 포함 여부, 포함한다면 어느 수준까지 보낼지 등)
정책 | 설명 | 예시 |
"no-referrer" | 어떤 경우에도 Referer 헤더를 보내지 않음 |
완전한 개인정보 보호
|
"no-referrer-when-downgrade" | HTTPS → HTTP 다운그레이드 시 Referer 생략. 나머지는 보냄 |
기본 동작 |
"same-origin" | 동일 출처에만 전체 URL 포함한 Referer 보냄 |
외부로 정보 유출 방지
|
"origin" | 출처만 포함 (경로 X) | 경로 생략 |
"strict-origin" | HTTPS → HTTP 다운그레이드 시 Referer 생략 나머지는 origin만 보냄 |
보안 강화 |
"origin-when-cross-origin" | 출처에 따라 자세히 보낼지 결정 - same-origin: 전체 URL - cross-origin: origin만 |
사용 흔함 |
"strict-origin-when-cross-origin" | HTTPS: 출처에 따라 자세히 보낼지 결정 HTTPS → HTTP는 생략. |
Chrome 기본값 |
"unsafe-url" | 항상 전체 URL 포함 (보안상 매우 위험) | 경로까지 노출됨 |
"" (빈 문자열) | 명시적 정책 없을 때 기본값 사용 ("no-referrer-when-downgrade") |
fallback |
설정) same-origin
더보기
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.referrerPolicy(referrer -> referrer
.policy(ReferrerPolicy.SAME_ORIGIN)
)
);
return http.build();
}
4. Permissions Policy
- 브라우저가 특정 Web API를 페이지나 iframe에서 사용할 수 있는지 제어하는 응답 헤더
기능 이름 | 설명 |
geolocation | 위치 정보 접근 |
camera | 카메라 사용 |
microphone | 마이크 사용 |
fullscreen | 전체 화면 요청 |
payment | Payment API |
clipboard-write | 클립보드 쓰기 |
accelerometer | 센서 정보 사용 |
usb | WebUSB 접근 |
예시) 헤더
더보기
Permissions-Policy: geolocation=(self)
예시) iframe
더보기
<iframe
src="https://example.com"
allow="geolocation 'self'; microphone 'none'">
</iframe>
설정) geolocation
더보기
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.permissionsPolicy(permissions -> permissions
.policy("geolocation=(self)")
)
);
return http.build();
}
5. Clear Site Data
- 브라우저의 데이터를 지우라고 명령하는 응답 헤더 (쿠키, 캐시, 로컬 스토리지 등)
- same-origin data만 삭제됨
- 로그아웃 등에서 자주 사용함
예시) 헤더
더보기
Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"
값 | 설명 |
"cache" |
브라우저 캐시 삭제 (HTTP 캐시 등)
|
"cookies" | 쿠키 삭제 (현재 도메인의 쿠키) |
"storage" |
로컬스토리지, 세션스토리지, IndexedDB 등 삭제
|
"executionContexts" |
서비스워커 등 실행 컨텍스트 제거 (탭을 새로고침해야 적용됨)
|
설정) logout - ClearSiteDataHeaderWriter
더보기
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.logout((logout) -> logout
.addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES)))
);
return http.build();
}
6. Custom Headers
- 기본 보안 헤더 외에, 직접 정의한 HTTP 헤더를 응답에 추가하는 기능
설정) static headers
더보기
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header","header-value"))
);
return http.build();
}
- 변하지 않는 고정된 값을 가진 HTTP 헤더
- 일반적으로 "X-" 접두어는 비표준 또는 사용자 정의 헤더를 나타내는 데 사용됩니다.
- 어플리케이션 내에서 특정 기능이나 정보를 전달하기 위해 사용될 수 있음
- ex) 특정 보안 정책, 세션 정보, 요청에 대한 추가 정보 등
설정) Headers Writer
더보기
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
);
return http.build();
}
- 사용자는 사용자 정의 HeadersWriter 인스턴스를 생성하거나 HeadersWriter의 사용자 정의 구현을 제공할 수 있습니다
설정) DelegatingRequestMatcherHeaderWriter
더보기
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
RequestMatcher matcher = new AntPathRequestMatcher("/login");
DelegatingRequestMatcherHeaderWriter headerWriter =
new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());
http
// ...
.headers(headers -> headers
.frameOptions(frameOptions -> frameOptions.disable())
.addHeaderWriter(headerWriter)
);
return http.build();
}
- 특정 조건에 맞는 요청에만 HTTP 헤더를 추가하고 싶을 때 사용함
출처
'Spring > Spring Security' 카테고리의 다른 글
[Spring Security] 5-4. 보안: HttpFirewall (0) | 2023.10.14 |
---|---|
[Spring Security] 5-3. 보안: HTTP Requests (0) | 2023.10.14 |
[Spring Security] 5-1. 보안: CSRF (0) | 2023.10.06 |
[Spring Security][KoLiving] 4-5. BlackList Token (0) | 2023.10.03 |
[Spring Security][KoLiving] 4-4. RefreshToken Rotation (0) | 2023.10.03 |