Spring Security headers, frameOptions, contentSecurityPolicy, HTTP Strict Transport Security(HSTS)
- -
Spring Security 에서 Http Response 에 대한 header 값을 설정하는 부분이 .headers 옵션이다.
기본적은 Spring Security headers 설정은 아래와 같다.
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: 1; mode=block
.frameOptions(X-Frame-Options)
Http 헤더에서 X-Frame-Options 속성을 설정하는데 프레임(iframe)에 웹사이트를 제한하거나 접근 허용 범위를 설정할 수 있다. 쉽게 말해 <iframe> 이라는 html 태그가 존재하는데 해당 태그안에 다른 웹페이지를 삽입할 수 있다.
해당 iframe 태그를 사용하게 되면 클릭재킹이라는 해킹공격에 취약하다.
* 클릭재킹
삽입하는 웹페이지 내 악의적인 코드를 집어 넣어 정상적인 동작처럼 보이게 만든 후 사용자의 정보를 갈취하거나
사용자를 속이는 공격이다.
기본적으로 Spring Security 에서는 DENY 설정하여 클릭 재킹 공격을 막는다.
옵션 종류
- DENY : iframe 삽입을 차단
=> X-Frame-Options: DENY - SAMEORIGIN : 동일 도메인 내에서 iframe 을 허용
=> X-Frame-Options: SAMEORIGIN
=> 예) example.com 의 페이지는 example.com 도메인 내에서만 iframe 삽입 가능 - ALLOW-FROM {도메인} : 특정 도메인 접근 가능
Content Security Policy(CSP)
CSP 란 웹 페이지에 대한 표준으로 , 스크립트, 스타일, 이미지 등의 리소스를 어떤 출처에서 로드할 수 있는지
명시하는 정책을 설정할 수 있다.
컨텐츠 보안 정책은 XSS 와 같은 컨텐츠 내의 인젝션 공격에 대한 취약점을 개선할 수 있는 설정이다.
위 설정을 보면 script-src 가 설정되어 있다.
javascript 에서 스크립트를 실행하게 되면 script-src 에 설정되어 있는 범위의 리소스가 맞는지 확인한 후
실행할지 결정한다.
script-src 'self' 다음 도메인에 대한 설정이 없으면 항상 스크립트를 실행할 수 없고
"script-src 'self' https://www.naver.com" 처럼 도메인이 설정되어 있으면 해당 도메인만 실행할 수 있다.
설정값
- default-src : src 로 끝나는 모든 리소스의 기본 동작을 설정
- script-src : Javascript 태그 관련 권한과 출처 설정
- style-src : 스타일시트 관련 권한과 출처 설정
- img-src : 이미지 관련 권한과 출처 설정
🎯 자주 사용하는 CSP 디렉티브
디렉티브 | 설명 |
default-src | 기본 리소스 (스크립트, 이미지 등)의 기본 출처 |
script-src | JS 파일 (외부 CDN 포함) |
style-src | CSS |
img-src | 이미지 |
font-src | 폰트 |
connect-src | AJAX/fetch/XHR 요청 |
frame-ancestors | 어떤 페이지가 <iframe>으로 내 페이지를 삽입할 수 있는지 (Clickjacking 방지용) |
object-src | <object>, <embed> 등 미디어 |
구성값
- none : 모든 출처를 허용하지 않음
- self : 동일 도메인 내에서 로드하는 리소스만 허용
- unsafe-inline : 인라인 코드의 사용을 허용
.headers(headers -> headers
.frameOptions(frameOptions -> frameOptions
.sameOrigin()
.contentSecurityPolicy(contentSecurityPolicy -> contentSecurityPolicy
.policyDirectives("script-src 'self'")
)
)
)
.sameOrigin().contentSecurityPolicy(csp -> csp
.policyDirectives("script-src 'self'")
)
.sameOrigin() 을 통해 같은 도메인상에서만 허용한다고 설정한다.
.contentSecurityPolicy 설정을 통해 CSP 설정을 하며 스크립트, 리소스, 이미지 등 어떤 출처에서 로드할 수 있는지
설정 가능하다.
본인은 인라인 스크립트인 <script></script> 내 스크립트 제한을 위해 "script-src 'self'" 설정을 했다.
***** 여기서 다른 방법이 있는걸 찾았다... *****
.headers(headers -> headers
.frameOptions(options -> options
.sameOrigin()
//.contentSecurityPolicy(csp -> csp.policyDirectives("script-src 'self'"))
)
.contentSecurityPolicy(csp -> csp
.policyDirectives("script-src 'self'")
)
)
.frameOptions 의 .sameOrigin() 하위에 있는 .contentSecurityPolicy 를 설정하지 않고
.headers 하위에도 .contentSecurityPolicy 가 있다.
두개다 동일한 성격을 띄지만 다른점은 앞으로 찾아보겠다...
contentTypeOptions(X-Content-Type-Options)
contentTypeOptions() 설정은 응답 헤더의 X-Content-Type-Options 를 설정하며
Spring Security 의 기본값은 "nosniff" 설정이며 컨텐츠 스니핑을 비활성화 한다.
.xssProtection
브라우저의 내장 XSS 필터를 활성화하거나 비활성화하는 설정이다.
📜 설정되는 헤더
X-XSS-Protection: 1; mode=block
✅ 주요 설정 방식
// Spring Security 6.5 버전 이하
.headers(headers -> headers
.xssProtection(xss -> xss
.block(true) // XSS 탐지 시 페이지 렌더링을 차단
.enabled(true) // 필터 활성화
)
)
// Spring Security 6.5 버전 (정확히 버전은 모르겠어요 ㅠ)
.headers(headers -> headers
.headerValue(HeaderValue.ENABLED_MODE_BLOCK)
)
⚠️ 주의
- 최신 브라우저(특히 Chrome, Edge) 는 이 헤더를 더 이상 지원하지 않는다.
- 구버전 브라우저를 위한 설정이다.
항목 | 설명 |
Spring Security 6.5에서 .xssProtection() 설정 방법 | .headerValue(HeaderValue.ENABLED_MODE_BLOCK) |
지원 enum 클래스 | org.springframework.security.web.header.writers.XXssProtectionHeaderWriter.HeaderValue |
자주 하는 실수 | server.header 패키지 enum을 잘못 쓰는 것 |
대안 (현대 브라우저 기준) | CSP 정책 사용 권장 |
HTTP Strict Transport Security(HSTS)
.headers(headers -> headers
.httpStrictTransportSecurity(hsts -> hsts
.includeSubDomains(true)
.preload(true)
.maxAgeInSeconds(31536000)
)
)
특정 웹사이트에 URL 을 적어 접근할때 https:// 처럼 문구를 생략하고 접근할때가 많다.
이러한 URL 접근은 중간자 공격에 취약하다.
이러한 취약점을 예방하기 위해 HSTS 설정이 필요하다.
HSTS 설정은 HTTP 로 액세스 하려는 모든 시도에 대해 HTTPS 요청으로 자동 변환해야 한다고 브라우저에게
알려주는 기능을 한다. 즉, 브라우저가 HTTP 대신 HTTPS 만 사용하도록 강제하는 설정이다.
쉽게 말해 사용자가 http 프로토콜로 접근했을 떄 브라우저에게 해당 웹사이트는 HTTPS 프로토콜로 접근해야
한다라고 미리 알 수 있게 한다.
HTTPS 로 서비스중일 때만 이 설정이 효과가 있다고 한다.
preload=true는 HSTS preload 리스트에 도메인이 등록되어야 실제로 적용된다.
- includeSubDomains(true) : 하위 도메인도 HSTS 도메인으로 취급해야한다 라고 알린다.
- preload(true) : 브라우저에게 이 도메인을 미리 HSTS 도메인으로 로드하도록 알린다.
- maxAgeInSeconds(시간) : 시간 설정
🧠 요약 표
설정 | 헤더 | 기능 | 상태 |
.xssProtection() | X-XSS-Protection | 브라우저 XSS 필터 설정 | ❌ 오래된 방식, 비추천 |
.httpStrictTransportSecurity() | Strict-Transport-Security | HTTPS 강제, MITM 방지 | ✅ 적극 권장 |
* 참고 내용
'Java > Spring' 카테고리의 다른 글
자바 8 표준 API의 함수형 인터페이스(Supplier, Consumer) (0) | 2025.01.07 |
---|---|
팩토리 메서드 패턴(Factory Method Pattern) (1) | 2025.01.03 |
Spring Security AuthenticationEntryPoint(인증), AccessDeniedHandler(인가) (0) | 2024.11.28 |
Spring Container, BeanFactory, ApplicationContext (2) | 2024.11.05 |
org.springframeworkbeans.factory.NoSuchBeanDefinitionException (Bean 을 찾을 수 없는 에러) (0) | 2024.10.28 |