Spring/Spring Security

[Spring Security] 5-2. 보안: Security HTTP Response Headers

noahkim_ 2023. 10. 14. 01:24

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 헤더를 추가하고 싶을 때 사용함
 
 
 
출처