HTTPS 프로토콜을 공부하다보면 여러가지 옵션과 개념들을 이해해야 하는데, 그중에 자주 만나게 되는 개념이 HSTS (HTTP Strict Transport Security) 입니다. 그럼 HSTS가 어떤 개념이고 왜 만들어졌으며 어떻게 적용이 가능한지 알아보도록 하겠습니다.
1. HSTS (HTTP Strict Transport Security) 란?
일반적으로 HTTPS를 강제하게 될 때 서버측에서 302 Redirect 를 이용하여 전환시켜 줄 수 있습니다. 하지만 이것이 취약점 포인트로 작용될 수 있습니다.
302 Redirect를 이용한 HTTPS 접속 유도
하여 클라이언트 (브라우저) 에게 HTTPS를 강제 하도록 하는 것이 권장되는데, 이것이 HSTS (HTTP Strict Transport Security) 입니다. 클라이언트 (브라우저)에서 강제 하기 때문에 Plain Text (HTTP) 를 이용한 연결 자체가 최초부터 시도되지 않으며 클라이언트 측에서 차단된다는 장점이 있습니다.
HSTS (HTTP Strict Transport Security) 를 이용한 HTTPS 접속유도
사용자가 최초로 사이트에 접속시도를 하게 되면 웹서버는 HSTS 설정에 대한 정보를 브라우저에게 응답하게 됩니다. 브라우저는 이 응답을 근거로 일정시간 (max-age) 동안 HSTS 응답을 받은 웹사이트에 대해서 https 접속을 강제화 하게 됩니다.
max-age 가 63072000초로써 rsec.kr은 최초 접속후 2년동안 브라우저에서 HTTPS접속이 강제화 됩니다.
이렇게 설정된 HSTS 내역은 클라이언트의 브라우저에서 확인 할 수 있는데, 크롬 브라우저의 경우는 아래와 같은 명령어로 확인이 가능합니다.
chrome://net-internals/#hsts
위 명령을 통하여 HSTS 를 적용 할 도메인을 직접 추가/삭제하거나 쿼리하여 내용을 조회 할 수 있습니다.
크롬에서 rsec.kr의 HSTS적용 여부 조회
HSTS는 이렇게 서버측 응답을 신뢰하여 브라우저에 일정시간 (max-age) 동안 등록이 되기도 하지만 google, twitter 등의 웹사이트는 구글 크롬 브라우저에 하드코딩 되어 HSTS가 Preload되어 강제화 되도록 되어있습니다. 관련 내용은 아래 링크를 통해 조회 하실 수 있습니다.
https://www.chromium.org/hsts
2. HSTS (HTTP Strict Transport Security) 의 설정방법
HSTS는 웹서버에서 응답해주는 헤더에 최초 포함되어 있는 만큼 웹서버에서 설정해 주어야 합니다. Nginx 의 경우는 아래와 같이 add_header를 추가 한 후 재시작하면 HSTS를 적용 할 수 있습니다.
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
위 설정에서 옵션들의 내용을 살펴보면
- max-age=63072000 : HSTS가 브라우저에 설정될 시간이며 초단위로 설정됩니다. 63072000은 2년을 의미합니다.
- includeSubdomains : HSTS가 적용될 도메인의 subdomain (www.rsec.kr 또는 mail.rsec.kr 따위) 까지 HSTS를 확장 적용함을 의미합니다.
- preload : HSTS 적용이 클라이언트 측에서 preload로 이루어짐을 의미합니다.
3. HSTS (HTTP Strict Transport Security) 의 설정 안정성 테스트 방법
하기 웹사이트에서 HSTS 적용이 잘 되어있는지 확인 할 수 있습니다.
https://hstspreload.org
rsec.kr 을 검색한 결과 아래와 같은 결과값을 얻을 수 있었습니다.
rsec.kr 의 인증서가 subdomain 까지 지원 할 수 없음을 경고 하였는데, 이것은 rsec.kr에서 사용하고 있는 Let’s encrypt 인증서가 아직 wildcard 인증서를 지원하고 있지 않아 생긴 문제 입니다. 향후 wildcard 인증서로 적용하면 해결 될 문제이니 넘어가도록 합시다.
4. HSTS (HTTP Strict Transport Security) 를 이용하여 SSL Strip 방어
일반적으로 잘 알려진 MITM (Man in the Middle) 공격을 보안하기 위함입니다. 일반적으로 TLS/SSL로 암호화 된 세션은 중간에서 공격자가 그 내용을 감청하더라도 암호화 되어 있기 때문에 데이터가 보호 될 수 있습니다.
그렇다면 SSL/TLS 로 암호화 된 세션을 강제로 암호화 하지 않은 HTTP 세션으로 유도한다면 어떨까요? 공격자는 중간에서 암호화 되지 않은 데이터를 감청함으로써 그 내용을 알 수 있을 겁니다. 이러한 방식을 SSL Strip 이라고 이야기 합니다.
- 사용자는 http://bank 로 연결 시도. 공격자는 그 연결을 그대로 웹서버에 전달
- 웹서버는 https 를 이용하여 연결하도록 응답
- 공격자는 웹서버의 응답을 조작하여 http로 연결하는 것처럼 사용자에게 응답
- 사용자는 응답받은 내용을 근거로 http로 연결. 공격자는 내용을 조회 한 후 https로 전환하여 웹서버에 연결을 전달
- 최종적으로 공격자는 ssl 을 strip하여 중간에서 내용을 감청 할 수 있음
일반적으로 위와 같이 이루어지는 SSL Strip 공격을 HSTS로 적용하게되면 클라이언트 (브라우저)에서 HTTPS 접속만 강제화 됨으로써 SSL Strip 공격을 방어 할 수 있습니다.
하지만 HSTS는 Sub Domain 을 통한 우회 방법 등 일부 설정이 누락되었을 경우 SSL Strip 공격이 가능합니다. 이 부분은 다음 포스팅에서 bittercap을 이용하여 그 내용을 포스팅 하도록 하겠습니다.
5. 결론 (Conclusion)
HSTS (HTTP Strict Transport Security) 는 HTTPS를 클라이언트의 브라우저에서 강제화 하여 최초 접속시 부터 HTTPS로 접속 할 수 있도록 유도하기 위해 만들어졌다고 볼 수 있습니다. HTTPS 를 이용한 웹사이트를 운영중이라면 필수로 설정하여 운영하도록 합시다!
https://hstspreload.org/ 이 사이트에 대한 정보를 추가합니다.
HSTS를 웹서버에서 리스폰스 헤더로 제공하는건 최초의 HTTP로 연결시에 HSTS 헤더가 내려오기전에 SSL 스트립이 가능한 문제가 여전히 존재합니다. 따라서 웹페이지에 들어가지 않고도 브라우저 내장 preload를 갖추는게 가장 안전한데, 저기 사이트에 조건 갖추고 제출하면 크롬 preload 리스트에 들어갈 수 있습니다. 크롬 리스트를 다른 브라우저도 공유하니까 한국에서도 많은 사이트가 preload 리스트에 올라가면 좋겠습니다
유익한 댓글 감사합니다~~
말씀하신 것과 같이 브라우저에서 프리로드 Public Key Pinning 을 하는게 가장 안전하겠죠~~~ ㅎㅎ
브라우저별로 아래링크에서 최신 정보를 확인 할 수 있는 것으로 알고 있습니다~
Chrome : http://src.chromium.org/viewvc/chrome/trunk/src/net/http/transport_security_state_static.json
Firefox :
https://dxr.mozilla.org/mozilla-central/source/security/manager/tools/PreloadedHPKPins.json
감사합니당~~ 🙂
안녕하세요 ㅎㅎ 취업을 준비중인 학생입니다. 다름이 아니라 HSTS에 대해 공부하면서 자료들을 찾아보다가 이곳 블로그에 들어오게 되었습니다. 내용이 너무 좋아서 내용과 사진을 참고해서 깃헙에 공부한 내용을 좀 올려도 될까…하고 이렇게 댓글 남기게 되었습니다. 허락해주신다면 당연히 출처 표시는 남기고 사용할 생각입니다!!