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를 미리 로드하려면 다음 단계를 따르는 것이 좋습니다.
- 사이트의 모든 하위 도메인을 검사하고 HTTPS를 통해 제대로 작동하는지 확인합니다.
- HSTS를 모든 HTTPS 응답에 헤더를 추가하고 max-age 헤더값을 단계적으로 증가시킵니다.
- 더 이상 문제가 없다고 확신되면 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>
참고 사이트
'Etc ( 기타 ) > 보안' 카테고리의 다른 글
SSL,TLS 프로토콜 버전 확인/테스트 방법 (0) | 2023.04.21 |
---|---|
openssl 사설 인증서 생성하는 방법 (0) | 2023.04.07 |
Blind SQL Injection란? (0) | 2022.11.20 |
Salt 비밀번호 암호화 방법 추천. Bcrypt (0) | 2022.10.30 |
password cracking이란? (0) | 2021.03.21 |