Etc ( 기타 )/보안

보안취약점 HSTS - HTTPS 강제하기

노루아부지 2021. 4. 11. 23:02

HTTPS로 웹 서비스를 올렸는데, 사용자가 HTTP로 접근하는 경우가 있습니다. 이 경우 보통 설정에서 HTTPS로 리다이렉트 시켜주는 경우가 많습니다.

하지만 이 리다이렉션 자체가 보안에 취약점이 될 수 있습니다. HTTP 요청을 가로채서 암호화되지 않은 정보를 볼 수 있기 때문입니다. 하지만 HSTS는 언제나 HTTPS를 강요하기 때문에 이를 방지할 수 있습니다.

 

그렇다면 HSTS란 무엇일까요?

 

HSTS(HTTP Strict Transport Security)란?

대부분의 웹 브라우저는 HSTS헤더(예: Strict-Transport-Security: max-age=15552000)를 발견하면 HTTPS(HTTP over Secure Socket Layer)로만 통신을 제한한다. 이는 SSL Strip 공격으로 HTTPS 네트워크 패킷을 감청할 수 있는 가능성을 줄이기 위한 방법이다. 로그인 페이지와 같이 중요정보가 전송되는 구간에는 HSTS를 적용하는 것이 좋다. HTTP 헤더 하나만 추가하면 되므로 네트워크에 거의 부담을 주지 않는 간단하면서도 효율적인 방법이다. (출처 : webhack.dynu.net/?idx=20161112.001 )

HSTS는 국제 인터넷 표준화 기구(IETF, Internet Engineering Task Force) 표준이며, RFC-6797로 세부내용이 기술되어 있습니다.

 

 

 

2. 배포 권장사항

사이트가 HTTPS로 HSTS를 미리 로드하려면 다음 단계를 따르는 것이 좋습니다.

 

  1. 사이트의 모든 하위 도메인을 검사하고 HTTPS를 통해 제대로 작동하는지 확인합니다.
  2. HSTS를 모든 HTTPS 응답에 헤더를 추가하고 max-age 헤더값을 단계적으로 증가시킵니다.
  3. 더 이상 문제가 없다고 확신되면 max-age를 2년을 늘리고 preload옵션을 추가합니다.

 

중요! preload 옵션을 추가하지 않으면 보안취약점 도구에 취약점으로 걸립니다.

 

 

 

3. HSTS 옵션

HSTS의 옵션은 아래와 같이 3가지 옵션이 있습니다.

  • max-age : 브라우저가 HSTS 정책을 적용할 기간(초)를 설정
  • includeSubdomains : 도메인(example.com)의 서브 도메인(api.example.com 등에도 HSTS 설정을 적용
  • preload : 해당 도메인이 블우저의 preload list에 추가되며 브라우저에서는 HSTS 헤더가 없더라도 HTTP 요청을 HTTPS로 강제 변환하여 전송

 

 

4. HSTS 설정 방법

1) Nginx

아래와 같은 헤더를 추가한 후 재시작 합니다.

add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

 

 

2) Spring Security

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      // ...
      .headers()
        .httpStrictTransportSecurity()
          .maxAgeInSeconds(31536000)
          .includeSubDomains(true)
          .preload(true)
          .and();
  }
}

 

 

단, 이 방법은 war로 export 하여 tomcat으로 구동하는 경우는 잘 적용이 되지 않는 것 같습니다.

이를 해결하기 위해서는 Tomcat의 server.xml 설정 파일의 Connector 설정에 scheme, secure 옵션을 추가하면 됩니다.

<Server ...>
  <Service ...>
    <Connector
      scheme="https"
      secure="true"
      ...
    />
  </Service>
</Server>

 

 

 

3) HSTS 설정 방법 - Tomcat

Tomcat의 web.xml에 아래와 같이 옵션을 추가하면 됩니다.

<filter>
  <filter-name>httpHeaderSecurity</filter-name>
  <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
  <async-supported>true</async-supported>
  <init-param>
    <param-name>hstsEnabled</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>hstsPreload</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>hstsMaxAgeSeconds</param-name>
    <param-value>31536000</param-value>
  </init-param>
  <init-param>
    <param-name>hstsIncludeSubDomains</param-name>
    <param-value>true</param-value>
  </init-param>
</filter>

 

 

 

 

참고 사이트

 

 

HSTS (HTTP Strict Transport Security) 개념과 Spring Security의 HSTS 설정 및 이슈 해결 과정

HSTS(HTTP Strict Transport Security)의 개념과 Spring Security의 HSTS 설정 방법 그리고 Nginx + Tomcat의 환경에서 HSTS 설정중 겪은 이슈에 대해 알아봅니다.

luckydavekim.github.io

 

Spring Security Reference

The authenticator is also responsible for retrieving any required user attributes. This is because the permissions on the attributes may depend on the type of authentication being used. For example, if binding as the user, it may be necessary to read them

docs.spring.io

 

Apache Tomcat 8 Configuration Reference (8.0.53) - Container Provided Filters

CORS Filter adds information about the request, in HttpServletRequest object, for consumption downstream. Following attributes are set, if cors.request.decorate initialisation parameter is true: cors.isCorsRequest: Flag to determine if request is a CORS re

tomcat.apache.org

 

728x90
loading