HSTS란

  • 사이트가 오직 HTTPS 통신만 할 수 있음을 접속하고자 하는 Browser에게 알려 주는 기능
  • 보안을 강화시킬 목적으로 Browser에게 HTTPS만 사용하도록 강제하는 기능
  • Browser에서도 HSTS 기능을 지원해야 HSTS 기능이 제대로 동작

 

  • 2010년 이후에 출시된 대부분의 Browser 버전에서는 HSTS 기능을 지원
  • HSTS (HTTP Strict Transport Security)는 HTTPS를 클라이언트의 브라우저에서 강제화하여 최초 접속 시부터 HTTPS로 접속할 수 있도록 유도하기 위해 만들어짐 → HTTPS를 이용한 웹사이트를 운영 중이라면 HSTS를 필수로 설정하여 운영해야 함
  • SSL Stripping 공격(SSL/TLS Hijacking)을 방지하기 위하여 HSTS 기능을 사용
  • 사용자가 실수로 HTTPS를 지원하는 Site를 HTTP접속 했을 때 중간자 공격에 의해 통신 정보가 공격자에게 노출이 되는 것을 방지하기 위해 강제로 HTTPS로 접속하기 위한 목적으로 사용
  • HSTS는 cookie hijacking을 방지하는 용도로도 사용됨
  • Browser에서 HSTS기능을 지원한다고 해도, SSL stripping 공격에 완전히 안전한 것은 아님

 

  • 공격자가 특정인을 대상으로 표적공격을 한다면 아래와 같은 방법을 취하여 HSTS를 무력화
    1. 특정인의 PC에 침투해서, Browser에 설정된 HSTS기능을 disable시킴
    2. HSTS List에서 특정 사이트에 대한 정보를 초기화

 

 

HSTS 기능의 동작

  1. Browser로 접속 시, 주소창에 “https://” 또는 “http://” 와 같은 프로토콜 이름을 입력하지 않고, 단지 도메인 이름(예를 들면, www.naver.com)만 입력
  2. Browser는 먼저 HTTP(“http://” 사용)로 해당 도메인에 접속을 시도
  3. 도메인 이름만 추출하여, HSTS List와 비교하여 존재하면(도메인 이름에 HSTS가 설정 O), HTTPS을 사용하여 접속
  4. 해당 도메인이 HTTPS만을 지원하는 사이트(HSTS)라면, ”301 Redirect” 또는 ”302 Redirect” response를 보내어 사이트가 HTTPS로 다시 접속하라고 지시
    • Browser가 이전에 접속한 적인 없는 HTTPS 지원 사이트에 HTTP로 접속하면, “301 Redirect” Reply Message로 다시 HTTPS로 접속
    • Server는 HTTPS Reply Message에 "HSTS Policy"를 넣어서 전송 → 암호화 되기 전 packet인, HTTP response header field에 "Strict-Transport-Security" 필드 정보 삽입
    • Browser는 위 정보를 받아서 내부 HSTS List를 구성
    • Server는 "Max Age 값", "Subdomain 적용여부 값", "Preloaded List에 추가여부 값"을 HTTP response header field에 담아 "Strict-Transport-Security" 함께 client에 전달
    • 만약, Web Browser가 HTTP Protocol로 Web Server에 접속하고, HTTP Reply Message에 HSTS Policy 정보가 들어 있는 경우는 무시
  5. 사이트는 status code로 HTTPS로 redirect를 인식한다면, 사용자는 주소창 옆에 있는 자물쇠 아이콘 또는 접속된 URL주소 앞에 “https://”를 보고, 해당 사이트가 HTTPS 지원함을 인식

 

 

HSTS response header의 Syntax

  • HSTS header example
    Strict-Transport-Security: max-age=<expire-time>
    Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
    Strict-Transport-Security: max-age=<expire-time>; preload

 

1. Max Age 값

  • HSTS List 에 존속하는 시간
  • Age 값이 0(zero)인 경우는 HSTS Policy를 삭제하라는 명령

 

2. Subdomain 적용 여부 값

  • subdomain에 HSTS를 적용할지 여부를 알려줌

 

3. Preloaded HSTS Lists

  • 이미 만들어져 있는 HSTS Lists를 Browser에 제공하는 기능도 지원 → "Preloaded HSTS Lists"
  • Preloaded HSTS Lists는 Browser 설치 또는 Update 할 때 Browser Vendor에 의해 제공
  • Preloaded HSTS Lists를 사용하는 목적은 SSL Stripping 공격을 방지하기 위한 목적
  • 사이트를 "Preloaded HSTS Lists"에 포함시키려면 "hstspreload.org" 사이트에 신청 → 요구하는 기능을 충족한 다음에 양식에 맞추어 신청
  • 사이트가 "Preloaded HSTS Lists"에 포함되어 있는 지 확인도 "hstspreload.org" 사이트에서 가능
  • HTTP만 지원하는 사이트를 HSTS List에 추가하거나, 공격자에 의해 HTTP을 지원하는 사이트로 Redirect 된 경우는, "Your connection is not private" 경고 메시지가 출력 → 접속 X
  • DNS Spoofing에 의한 Redirection은 IP 주소 자체가 변경되는 경우는 여기에 해당 X
  • "HSTS Lists""Preloaded HSTS List"가 각각 존재하는 것이 아니고, 개념상 미리 만들어져 있는 "HSTS Lists""Preloaded HSTS Lists"라고 칭함

 

 

HSTS 응답을 받는 웹 사이트에 대해서 https 접속을 강제화

  • max-age가 63072000초로써 rsec.kr은 최초 접속 후 2년 동안 브라우저에서 HTTPS 접속 강제화

 

  • 설정된 HSTS 내역은 클라이언트의 브라우저에서 확인할 수 있는데, 크롬 브라우저의 경우는 아래와 같은 명령어로 확인 가능 (크롬 브라우저 주소창에 입력)
    1. 브라우저 사용자가 직접 특정 사이트를 HSTS List에 추가하는기능 제공
    2. Chrome Browser 인 경우는, 주소창에 “chrome://net-internals/#hsts” 입력하여 설정
    3. 설정된 값을 확인 및 삭제도 가능
    4. HSTS 접속 URL : chrome://net-internals/#hsts

 

  • 위 명령을 통하여 HSTS 를 적용할 도메인을 직접 추가/삭제하거나 쿼리하여 내용을 조회 가능
  • HSTS는 서버 측 응답을 신뢰하여 브라우저에 일정시간 (max-age)동안 등록이 되기도 하지만 google, twitter 등의 웹사이트는 구글 크롬 브라우저에 하드코딩 되어 HSTS가 Preload되어 강제화 되도록 되어 있음
  • 관련 내용은 아래 링크를 통해 조회 가능 (https://www.chromium.org/hsts)
 

HTTP Strict Transport Security

HTTP Strict Transport Security HTTP Strict Transport Security allows a site to request that it always be contacted over HTTPS. HSTS is supported in Google Chrome, Firefox, Safari, Opera, Edge and IE (caniuse.com has a compatibility matrix). The issue that

www.chromium.org

 

 

HSTS (HTTP Strict Transport Security)의 설정 방법

  • HSTS는 웹서버에서 응답해주는 헤더에 최초 포함되어 있는 만큼 웹서버에서 설정 필요
  • Nginx의 경우는 아래와 같이 add_header를 추가한 후 재시작하면 HSTS를 적용 가능
    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

 

  • HSTS 설정에 대한 옵션
    1. max-age=63072000
      • HSTS가 브라우저에 설정될 시간이며 초단위로 설정
      • 63072000은 2년을 의미
      • 63072000 = 2 * 365 * 24 * 60 * 60

    2. includeSubdomains
      • HSTS가 적용될 도메인의 subdomain (www.rsec.kr 또는 mail.rsec.kr 따위)까지 HSTS를 확장 적용함을 의미

    3. preload
      • HSTS 적용이 클라이언트 측에서 preload로 이루어짐을 의미

 

 

HSTS (HTTP Strict Transport Security)의 설정 안정성 테스트 방법

  • https://hstspreload.org 웹사이트에서 HSTS 적용이 잘 되어있는지 확인 가능
  • rsec.kr 을 검색한 결과 아래와 같은 결괏값을 추출

 

  • rsec.kr의 인증서가 subdomain까지 지원할 수 없음을 경고하였는데, 이것은 rsec.kr에서 사용하고 있는 Let’s encrypt 인증서가 아직 wildcard 인증서를 지원하고 있지 않아 생긴 문제
  • 향후 wildcard 인증서로 적용하면 해결될 문제 가능
  • https://hstspreload.org 웹사이트 HSTS 확인
 

HSTS Preload List Submission

<!-- We un-hide the form using inline JS so that (when JS is enabled) it shows in the normal rendering order as if it was never hidden. --> Submitting entries to the HSTS preload list via this site requires JavaScript. This form is used to submit domains f

hstspreload.org

 

 

HSTS (HTTP Strict Transport Security)를 이용하여 SSL Strip 방어

  • MITM (Man in the Middle) 공격 방어
  • TLS/SSL로 암호화된 세션은 중간에서 공격자가 그 내용을 감청하더라도 암호화 되어 있기 때문에 데이터가 보호 가능
  • 그렇다면 SSL/TLS 로 암호화 된 세션을 강제로 암호화하지 않은 HTTP 세션으로 유도한다면 어떨까요?
  • 공격자는 중간에서 암호화 되지 않은 데이터를 감청함으로써 그 내용을 알 수 있을 겁니다.
  • 아래의 SSL Strip 공격을 HSTS로 적용하게 되면 클라이언트(브라우저)에서 HTTPS 접속만 강제화 됨으로써 SSL Strip 공격을 방어 가능
  • HSTS는 Sub Domain 을 통한 우회 방법 등 일부 설정이 누락되었을 경우 SSL Strip 공격이 가능

    ※ SSL Strip
    • SSL/TLS로 암호화 된 세션을 강제로 암호화하지 않은 HTTP 세션으로 유도한다면 공격자는 중간에서 암호화되지 않은 데이터를 감청함으로써 내용을 알 수 있음
    • sslstrip이라 불리는 tool을 사용하면, SSL Stripping을 구현 가능
    • sslstrip은 중간자(Man-In-The-Middle) 위치에 있으면서 양쪽(Browser와 Server)을 모두 속이면서 동작
    • HSTS 기능이 없다면, sslstrip은 공격자가 운영하는 Proxy Server 역할

  • SSL Strip 공격하는 과정
    • sslstrip이 중간에서 traffic을 가로챌 수 있도록 하려면, 먼저 ARP poisoning(또는 ARP spoofing) 공격을 수행 → server로 향하는 트래픽을 sslstrip으로 가게 함
    • 사용자는 http://bank 로 연결 시도. 공격자는 그 연결을 그대로 웹서버에 전달
    • 웹서버는 https를 이용하여 연결하도록 응답
    • 공격자는 웹서버의 응답을 조작하여 http로 연결하는 것처럼 사용자에게 응답
    • 사용자는 응답받은 내용을 근거로 http로 연결. 공격자는 내용을 조회한 후 https로 전환하여 웹서버에 연결을 전달
    • 최종적으로 공격자는 ssl 을 strip 하여 중간에서 내용을 감청할 수 있음

 

  • ARP poisoning (ARP spoofing)
    • 동일한 subnet상에서 이루어지는 것
    • ARP poisoning은 ARP cache 값, 즉 IP 주소에 대응되는 MAC 주소 값을 조작하는 공격
    • SSL Strip은 HTTP로 통신하는 모든 내용을 sslstrip.log 파일에 기록해 두는 기능을 제공
    • SSL Strip.log 파일을 통해 Server 접속자의 개인 정보를 추출 가능
    • 실제 환경에서는 공격자가 SSL Strip과 유사한 기능을 가진 악성코드를 설치하여 민감한 정보를 탈취

 

 

Content-Length: 엔터티의 길이

  • Content-Length 헤더는 메시지의 엔터티 본문의 크기를 바이트 단위
  • 어떻게 인코딩 되었든 상관없이 크기를 표현
  • Content-Length 헤더는 메시지를 청크 인코딩으로 전송하지 않는 이상, 엔터티 본문을 포함한 메시지에서는 필수적으로 있어야 함
  • 서버 충돌로 인한 메시지 잘림 검출과 지속 커넥션을 공유하는 메시지를 분할하고자 할 때 필요

1. 잘림 검출

  • 오래된 버전의 HTTP는 커넥션이 닫힌 것을 보고 메시지가 끝났음을 인지
  • Content-Length가 없다면 커넥션이 정상적으로 닫힌 것인지 구분하지 못함
  • 메시지 잘림은 캐싱 프록시 서버에서 특히 취약
  • 캐시가 잘린 메시지를 수신했으나 잘렸다는 것을 인삭하지 못했다면, 캐시는 결함이 있는 컨텐츠를 저장하고 계속해서 제공.
  • 결함있는 컨텐츠를 제공하는 것을 방지하기 위하여, 캐싱 프록시 서버는 명시적으로 Content-Length 헤더를 갖고 있지 않은 HTTP 본문은 캐시하지 않음

2. 잘못된 Content-Length

  • Content-Length가 잘못된 값을 담고 있을 경우 아예 빠진 것보다도 큰 피해를 유발함
  • HTTP/1.1에서는 사용자 에이전트가 잘못된 길이를 받고 이를 인지했을 때, 사용자에게 알려주게 됨

3. Content-Length와 지속커넥션

  • Content-Length는 지속 커넥션을 위해 필수
  • 클라이언트에게 메시지 하나가 어디서 끝나고, 다음 시작은 어디인지 알려줌
  • 커넥션은 지속적이기에, 클라이언트가 커넥션이 닫힌 위치를 근거로 메시지의 끝을 인식하는 것은 불가능
  • HTTP 애플리케이션은 엔터티 본문의 길이와 끝을 인식하고자 Content-Length 헤더를 활용
  • 청크 인코딩을 사용하는 경우는 예외
  • 청크 인코딩은 데이터를 특정 크기를 갖는 청크들로 쪼개어 보내며, Content-Legnth 헤더를 필요로 하지 않음


컨텐츠 인코딩

  • HTTP는 보안을 강화하거나 압축을 통해 공간을 절약할 수 있도록, 엔터티 본문을 인코딩할 수 있게 해줌
  • 만약 본문의 컨텐츠가 인코딩되어 있다면, Content-Length 헤더는 원본이 아닌 인코딩된 본문을 바이트 단위로 정의함
  • HTTP/1.1 명세에서 어떤 헤더도 인코딩 전 원본의 길이를 보내고자 사용되지 않음
  • 클라이언트가 수행한 디코딩 과정의 검증을 어려움
  • Content-MD5 헤더도 인코딩된 문서의 MD5를 담음 → 자주 사용 X

  • ALPN은 Application Layer Protocol Negotiation의 약어
  • ALPN(Application-Layer Protocol Interval)은 "Hello 메시지" 교환 내에 프로토콜 협상을 포함하는 TLS 확장
  • ClientHello의 확장 기능으로, TLS handshake 이후에 application layer의 프로토콜과 버전을 결정하기 위한 기능
  • ALPN → 프로토콜을 협상

    1. secure connection을 통해 처리
    2. 효율적인 접속
    3. 추가적인 round trips을 방지


  • HTTP/2 프로토콜은 ALPN을 사용하여 웹사이트 로딩 시간을 줄이고 연결을 더 빠르게 암호화함

  • 핸드셰이크 프로세스는 client에서 server까지 왕복 2회에 해당

  • round trips이 많을수록 대기 시간은 길어지고 사용자는 서버로부터 정보를 받기 위해 더 오래 기다려야 함

  • round trips의 수는 주로 client와 server(ex.. DNS, TCP, HTTP) 간의 통신을 시작하기 위한 핸드셰이크에서 발생

  • round trips이 적은 상태에서 데이터를 전송하는 프로토콜을 개선할 수 있다면, 페이지 로딩 시간도 개선 가능

  • ALPN은 HTTP/2에서는 HTTP의 버전을 합의하기 위해서 ALPN을 사용
    1. 먼저 client가 자신이 HTTP/1.1과 2를 지원한다는 사실을 ALPN으로 전송
    2. server가 ALPN과 HTTP/2를 지원한다면 ServerHello의 확장 필드에 h2를 적으면 handhshake 이후 HTTP/2로 통신이 시작
    3. ALPN을 지원하지 않으면, ServerHello에 ALPN 필드가 없으므로 HTTP/1.1로 통신


TLS handshake 동작 원리

  • ALPN 확장을 사용할 경우의 이점을 완전히 이해하기 위해서는 먼저 TLS 핸드셰이크가 어떻게 작동하는 지 숙지할 필요가 있음

1. TLS handshake 단계 (TLS 포함)

  1. client와 server는 "Hello 메시지"를 교환하여 알고리즘에 합의하고 랜덤 값을 교환(exchange random value)하며 세션 재개(session resumption)를 확인
  2. 필요한 암호 파라미터(cryptographic parameters)의 교환을 통해 client와 server가 premaster secret를 허용
  3. master secret은 premaster secret에서 생성되고 임의의 값을 교환
  4. record layer에 security parameters를 제공
  5. client와 server는 peer가 동일한 security parameters를 계산했는지, 공격자가 조작하지 않고 handshake가 발생했는지 확인

2. premaster secret

  • Client는 세션키를 생성하여 서버에게 전송
  • 암호화된 세션키를 premaster secret이라고 함

3. master secret

  • 서버측에서 복호화할 때 사용
  • premaster secret을 통해 master secret가 생성
  • premaster secret을 사용하여 master secret를 복호화 → 데이터 추출 가능


ALPN의 동작 원리

  1. ALPN client는 "TLS ClientHello 메시지"가 지원되는 application protocol 목록을 server로 전송 → "ClientHello 메시지" 안에 지원하는 목록을 가진 ProtocolNameList 필드를 추가
  2. 목록을 수신한 server는 프로토콜을 선택하고 "ServerHello 메시지"로 프로토콜을 다시 전송 → 수신한 ProtocolNameList 필드를 살피고 "SeverHello 메시지"의 일부에 선택된 프로토콜을 나타내는 ProtocolName 필드를 반환
  3. Server는 하나의 프로토콜 명을 응답하겠지만, 만약 Client가 요청한 목록에서 지원되는 것이 없다면 연결은 끊어지게 됨
  4. 일단 TLS hadnshake가 완료되면 보안 연결이 수립되고 Client 와 Server는 어떤 응용프로그램 프로토콜을 사용할지 동의
  5. 협상된 프로토콜을 통해 Client와 Sever는 바로 메시지를 교환 가능
  6. aplication protocol negotiation은 TLS handshake 내에서 하나의 round trip에서 달성
  7. 위 방법은 server가 각 application protocol에 다른 인증서를 연결할 수 있도록 함
  8. support protocols 목록은 first message에서 server로 전송되어 필요한 왕복 여행의 양을 최소화


NPN vs ALPN (NPN과 ALPN의 비교)

1. NPN(client가 프로토콜 선택)

  • Next Protocol Negotiation의 약어
  • TLS Handshake 중에 효과적인 응용프로그램 프로토콜 협상을 위해서 구글에서 개발한 SPDY의 일부로 개발된 TLS 확장
  • NPN은 ALPN의 전신이며 SPDY와 함께 널리 사용 (ALPN과 상당히 유사)
  • NPN은 "ClientHello 메시지"에 지원되는 프로토콜 목록을 포함 X → ALPN과 차이
  • NPN extension에서는 "ClientHello 메시지"에 프로토콜 목록이 포함되지만 일반적인 NPN은 client가 선택할 수 있는 프로토콜 목록을 다시 보내는 것은 server이다.

2. ALPN (server가 프로토콜 선택)

  • NPN을 업그레이드 한 버전(client와 server의 프로토콜 목록 전송은 반대 과정)
  • ClientHello 메시지는 server가 선택할 수 있도록 지원되는 프로토콜 목록을 포함
  • ALPN은 "ClientHello 메시지"를 받은 이후 리소스 선택 프로세스(resource selection process)를 시작할 수 있어 역방향 프록시(reverse proxy)에도 유리
  • ALPN이 다른 프로토콜 협상 표준과 더 유사


ALPN의 성장

  • HTTP/2는 사용자 경험 향상(better user experience)과 로딩 시간 단축(faster load times)으로 인기가 높아짐 → ALPN 확장이 HTTP/2와 결합하여 제공됨으로 ALPN도 같이 성장
  • 2016년 SPDY가 공식 폐지되면서 HTTP/2의 성장이 두드러짐
  • 인상적인 속도 및 강화된 보안 기능으로 ALPN 발전
  • 웹 사이트에서 HTTP/2 및 ALPN을 지원하는지 확인 : https://gf.dev/http2-test


참고 자료 : https://www.ietf.org/proceedings/88/slides/slides-88-httpbis-1.pdf

  • 특수문자 %20는 공백(스페이스), 즉 "빈 칸"을 의미

  • 인터넷 주소에서는 원칙적으로 빈 칸이 들어갈 수 없음

  • 빈 칸(공백)은 하나의 글자 → 공백문자의 아스키 코드(ASCII Code)는 10진수로는 32, 16진수로는 20임

  • ASCII Code의 20를 활용하여 빈 칸을 인터넷 주소에서 %20으로 사용


  • 아래처럼 빈칸이 있는 경우 호출 불가

    http://www.baidu.com/Hello Test.html

  • 빈칸이 있는 주소에서 빈 칸을 %20 으로 변환하는 경우 호출 가능

    http://www.baidu.com/Hello%20Test.html

+ Recent posts