회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
AWS 이용 중이라면 최대 700만 원 지원받으세요
대부분의 웹 사이트는 보안성을 위해 HTTPS를 지원합니다. 상업적인 웹 사이트뿐만 아니라 개인 블로그까지 이제 HTTPS는 선택이 아니라 거의 강제에 가까운 옵션이라 할 수 있습니다. 최신 브라우저들은 HTTPS를 지원하지 않는 웹 사이트를 위험성이 있는 페이지로 표시하고 있으며, 검색 엔진 또한 HTTPS를 적용한 사이트를 검색 결과에 우선적으로 노출하고 있습니다.
회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!
확인
대부분의 웹 사이트는 보안성을 위해 HTTPS를 지원합니다. 상업적인 웹 사이트뿐만 아니라 개인 블로그까지 이제 HTTPS는 선택이 아니라 거의 강제에 가까운 옵션이라 할 수 있습니다. 최신 브라우저들은 HTTPS를 지원하지 않는 웹 사이트를 위험성이 있는 페이지로 표시하고 있으며, 검색 엔진 또한 HTTPS를 적용한 사이트를 검색 결과에 우선적으로 노출하고 있습니다.
적잖은 가격으로 부담이 되었던 SSL/TLS 인증서는 Let's Encrypt와 같은 오픈 소스 기반의 무료 인증서나, 퍼블릭 클라우드 제공사와 CDN 사업자가 무료로 제공하는 인증서 등을 적용해 쉽게 사용할 수 있게 되었습니다.
그렇지만 아직도 HTTPS를 사용하지 않는 웹 사이트와 클라이언트는 존재합니다. HTTPS의 작동 원리를 살펴봤던 1편에 이어, 이번 글에서는 브라우저가 웹 서버와 통신 시, 무조건 HTTPS 통신을 할 수 있도록 수행하는 HSTS 기술에 대해 알아보겠습니다.
HSTS(HTTP Strict Transport Security, RFC6797)는 웹 사이트 접속 시 HTTPS만 사용하도록 강제하는 기술입니다. HSTS가 적용된 웹 사이트의 웹 서버는 클라이언트에게 HTTPS만을 사용할 수 있음을 알려주고, HSTS를 지원하는 브라우저는 이를 해석하고 적용합니다. 대부분 최신 버전의 브라우저들은 모두 HSTS를 지원하고 있습니다.
HSTS를 사용하지 않는 경우, 일반적으로 HTTPS로의 접속 유도 방법은 웹 서버에 다음과 같은 페이지 재전송 설정을 만드는 것이었습니다.
① 사용자는 HTTP 방식으로 본인이 접속하려는 웹 사이트의 주소를 브라우저 주소창에 입력한다.
② 웹 서버는 HTTP 접속에 대해 보통 301 혹은 302 응답으로 HTTPS 사이트로 페이지를 재전송한다.
③ 사용자의 브라우저는 비로소 안전한 HTTPS 방식으로 다시 웹 서버에 접속한다.
위의 방법은 잘 동작하지만 사실 ①번 단계에서 사용자는 이미 HTTP 접속을 요청했기 때문에, 사용자와 같은 네트워크 상에서 사설 프록시나 해킹 도구를 운영하는 해커들은 중간자 공격의 형태로 사용자의 HTTP 패킷을 몰래 캡처하고, 쿠키 값 혹은 세션 정보 등의 민감한 사용자 데이터를 엿볼 수 있습니다.
HSTS를 적용한 도메인은 사용자가 처음으로 웹 서버에 접속할 때 응답 헤더에 Strict-Transport-Security라는 헤더를 내려보내고, HSTS를 지원하는 브라우저라면 추후 접속부터는 HTTPS로만 접속합니다.
Strict-Transport-Security 응답 헤더는 다음과 같이 설정합니다.
Strict-Transport-Security: max-age=[적용 주기] max-age 값은 초(second) 단위며, 해당 시간 동안 HSTS 응답을 받은 웹 사이트에 대해 HTTPS 접속만을 허용한다는 의미
Strict-Transport-Security: max-age=[적용 주기]; includeSubDomains HSTS가 해당 도메인의 서브 도메인에도 적용되고 있음을 알려줌
Strict-Transport-Security: max-age=[적용 주기]; preload 브라우저의 Preload List에 해당 도메인을 추가할 것을 알려줌 |
HSTS가 적용된 페이스북을 예제로 위의 내용을 살펴보겠습니다. 먼저 페이스북 페이지에 HTTP로 접속해 봅니다.
curl -v http://www.facebook.com/ ... ...(중간 생략) ... < HTTP/1.1 301 Moved Permanently < Location: https://www.facebook.com/ < Content-Type: text/plain < Server: proxygen-bolt < Date: Sat, 24 Dec 2022 11:07:52 GMT < Connection: keep-alive < Content-Length: 0 |
HSTS가 적용된 웹 사이트지만 HTTP로 접속하면 Strict-Transport-Security 헤더는 보이지 않고, 그냥 HTTPS가 적용된 페이지로 재전송하는 로직이 보일 뿐입니다. HTTP는 안전한 프로토콜이 아니고 전달 중간에 응답이 변조될 수 있기 때문에, 일반적으로 HSTS 응답 헤더는 HTTPS 요청에 대해서만 설정합니다.
페이스북에 HTTPS로 접속하면, 예제의 마지막 라인처럼 Strict-Transport-Security 헤더를 볼 수 있습니다. 이 헤더가 바로 HSTS를 적용하겠다는 웹 서버의 응답 헤더이며, HSTS를 지원하는 브라우저는 이를 해석하고 적용합니다.
curl -v https://www.facebook.com/ ... ...(중간 생략) ... < HTTP/2 200 < vary: Accept-Encoding < cross-origin-opener-policy: same-origin-allow-popups < pragma: no-cache < cache-control: private, no-cache, no-store, must-revalidate < expires: Sat, 01 Jan 2000 00:00:00 GMT < x-content-type-options: nosniff < x-xss-protection: 0 < x-frame-options: DENY < strict-transport-security: max-age=15552000; preload < content-type: text/html; charset="utf-8" ...(중간 생략) |
여기서 max-age란 HSTS를 언제까지 적용할 것인가에 대한 설정값입니다. 페이스북은 15552000초로 설정되어 있고 이는 180일에 해당하는 값입니다. preload 지시자는 HSTS Preload List를 적용하겠다는 의미입니다.
이제부터 HSTS 응답 헤더를 받은 브라우저는 180일 동안 페이스북에 HTTPS로만 접속하게 됩니다. 만약 브라우저가 페이스북에 HTTP로 접속하려 한다면, 브라우저는 위와 같이 307 Internal Redirect 응답으로 HTTPS가 적용된 페이지로 내부 재전송합니다.
본래 307 응답은 Temporary Redirect라는 의미를 가지고 있습니다. 위 예제에서 응답 코드와 Non-Authoritative-Reason 헤더의 값을 통해, HSTS 설정은 별도의 DNS 접속이나 외부 인터넷 사용 없이 내부적으로 HTTPS를 재전송함을 알 수 있습니다. 즉 보안적으로 위험한 브라우저와 웹 서버 간 HTTP 통신이 아예 제거되었다는 의미입니다.
HSTS Preload List란 HSTS가 적용된 웹 사이트의 명단을 모아둔 리스트 정보입니다. HSTS Prelist List에 포함된 사이트들은 그 사이트를 처음 접속하는 브라우저, 즉 사전에 Strict-Transport-Security 응답 헤더를 받은 적이 없어도 HTTPS로만 접속합니다. 한 번이라도 접속해야만 적용 가능한 HSTS를 첫 방문부터 적용하여, HTTPS 만으로 접속하기 위해 만들어진 리스트라는 의미입니다.
이 리스트는 구글이 운영하는 hstspreload.org 사이트에 등재되어 있는데요. 이 사이트는 크롬 브라우저만의 HSTS Preload List를 서비스합니다. 여기에 등록된 사이트는 크롬 브라우저 내부에 하드 코딩되어 HTTPS로만 접속 가능합니다. 사파리 혹은 엣지 브라우저도 hstspreload.org에 기반한 자체적인 HSTS Preload List를 운영합니다.
또한 위 사이트를 통해 어떤 도메인이 리스트에 포함되었는지 조회가 가능한데요. 앞에서 테스트한 것처럼 페이스북의 등록 여부를 조회할 수 있습니다.
네이버의 경우 리스트에는 없지만 서비스를 살펴보면, HSTS가 적용되어 관련 응답 헤더가 존재합니다. 아래 테스트에서 알 수 있듯이 HSTS를 사용하지만 아직 리스트 명부에는 없는 상태입니다.
curl -v --silent https://www.naver.com/ 2>&1 | grep strict < strict-transport-security: max-age=63072000; includeSubdomains |
위의 값을 해석하면 네이버의 HSTS 적용 주기는 63072000초(730일)이며, includeSubdomains 옵션을 통해 서브 도메인들까지 모두 HSTS가 적용되도록 설정되어 있습니다.
HSTS Preload List에 등록되지 않은 이유로는 http://naver.com로 접속 시, https가 아닌, http://www.naver.com으로 페이지가 재전송되기 때문일 수도 있습니다. 실제로 HSTS Preload List에 등록 후 SSL 인증서 만료 등으로 HTTPS 사용에 문제가 생기면 서비스에 아예 접속을 못하는 상황이 생길 수도 있고, HTTP 프로토콜로 다운그레이드를 하려면 리스트에서 도메인을 삭제하는 데 많은 시간이 걸립니다. 그래서 도메인 관리자는 리스트 등록 여부를 신중하게 결정해야 합니다.
특히 CDN 서비스들은 브라우저 사용자들이 인터넷 네트워크상에서 접속하는 첫 번째 관문이므로, HTTPS 적용이 매우 중요합니다. 따라서 쉽게 HSTS를 적용할 수 있는 기능을 제공합니다.
지금까지 안전한 웹을 위해 HTTPS 사용을 강제하면서, 보안 취약성은 제거한 HSTS 기술과 적용 방법에 대해 알아보았습니다. 현재 개인 혹은 회사 사이트에 HTTPS는 적용했지만, 아직 HSTS 혹은 HSTS Preload List를 적용하지 않았다면, 지금이라도 적용 여부를 고려해 안전한 웹 사이트 환경을 만드시길 바랍니다.
요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.