HTTPS 보안
HTTPS란 암호로 통신해서 보안을 높이는 프로토콜입니다.
HTTPS와 보안
보안과 암호는 뗄레야 뗄 수 없는 관계입니다. 암호의 역사는 깁니다. 고대 그리스에선 전쟁 시 정보를 아군들만 알도록 암호를 썼고, 중세 배경의 창작물을 보면 실링 왁스로 편지를 봉하거나, 특정 단어를 치환하거나 은유를 사용하죠. 이처럼 메시지 발각과 변조를 막는 노력은 끊임없었습니다.

사람이 기억하고 써야 하므로 초기 암호화(encryption, encoding), 복호화(decryption, decoding)방법은 어렵지 않았습니다. 하지만 이는 허술한 보안이었고, 사람들은 점점 더 복잡한 암호를 도입했습니다.
암호 키
현대 암호 체계는 하나의 암호화 알고리즘을 가지되, 암호 키에 따라서만 암호화가 달라지는 구조를 많이 씁니다. 이는 케르크호프스의 원리(kerckhoffs's principle)에 따릅니다. 암호 체계 자체는 비밀스러울 필요가 없을 뿐더러, 적에게 넘어가더라도 아무런 문제가 없어야 합니다. 키의 비밀성만 지키면 되는 시스템이 중요합니다.

내가 "Hello Alice!"를 그대로 보내면 누군가가 훔쳐볼 수 있으므로, 암호 6EB69570...으로 변환해서 보냅니다. Alice는 암호를 받아서 "Hello Alice!"라는 문장으로 해독해서 읽죠.
이는 간결하면서도 직접 파훼하기는 굉장히 어려운 보안 시스템입니다. 개인 암호 키를 매번 바꿔서 쓴다면 보안은 더욱 철저해지겠죠.
HTTPS와 TLS
HTTPS는 웹 요청에 위의 방식을 적용한 개념입니다. SSL 혹은 TLS(Transport Layer Security)라는 프로토콜을 거쳐서 트래픽을 암호로 바꿉니다.

기존 HTTP 통신은 요청과 응답 메시지 내용이 고스란히 노출됩니다. 메시지가 중간에 탈취당한다면 중요한 정보가 들키죠. 우리는 평범하게 작성한 요청과 응답을 주고받지만, HTTPS가 자동으로 암호화와 복호화를 수행합니다. HTTPS가 필수인 이유입니다.

TLS 핸드셰이크는 클라이언트와 서버가 서로 어떻게 암호를 주고 받을지 협의하고 암호 키를 주고받습니다. 암호 키는 통신이 새로 열릴 때마다 발급하며 이를 세션 키라고도 부릅니다. 암호화 패턴이 매번 달라지므로 보안이 엄중해지겠죠.
현대에는 256비트 암호 키를 지원하는 서비스가 흔한데, 이는 2의 256제곱 만큼의 케이스가 발생한다는 뜻이고, 1초에 1조 가지 케이스를 시험하는 슈퍼 컴퓨터로 이를 해킹하려면 10의 61제곱년이 넘게 소요됩니다. 우주의 나이를 아득히 뛰어넘습니다. HTTPS는 보안 수준을 매우 높였습니다.
HTTPS로 암호화된 메시지는 절대 안전을 보장할까요? 페이스북이 그 반례를 보여줍니다.
페이스북의 중간자 공격

2019년 페이스북에선 유저에게 Onavo Protect라는 VPN 앱을 설치하게 했습니다.
VPN은 클라이언트와 서버 사이에 위치하기 때문에 컨텐츠를 필터링할 수도 있습니다. 청소년에게 유해한 컨텐츠를 차단한다던지, 회사의 기밀 유출을 검사한다던지요. 이는 SSL Bumping이라고 하는, 보안 목적의 기술입니다.
암호화된 트래픽을 중간자가 검사한다는 것은 민감한 사항입니다. 예시만 봐도 개인보다는 '특정한 조직' 단위에서 이용하는 게 적절하죠.
페이스북은 왜 이런 VPN을 개인 사용자들에게 요구했을까요? 이들은 사용자가 다른 앱(Snapchat, YouTube, Amazon 등)과 주고받는 트래픽을 훔쳐보려는 목적이 있었습니다.

페이스북은 사용자 기기에 자신들의 자체 인증서를 "신뢰할 수 있는 인증서"로서 설치시켰습니다. 이를 통해 페이스북은 사용자와 타사 앱을 대신해서 소통할 권한을 가지게 됐습니다. 사용자는 페이스북을 Snapchat이라고 믿고, Snapchat은 페이스북을 사용자라고 믿으며 소통해온 것 이죠. 이러한 공격을 MITM(Man In the Middle attack, 중간자 공격)이라고 합니다.
이 케이스는 "기업이 사용자를 기망한 케이스"입니다. 그렇다면 해커가 HTTPS를 뚫고 공격할 일은 없을까요? 당연히 있습니다.
SSL/TLS 다운그레이드 공격

SSL/TLS 다운그레이드 공격은 취약한 Wi-Fi라던지, DNS를 조작하거나 라우터를 속이는 등의 방법으로 해커가 중간에 끼어든 다음, SSL/TLS 프로토콜을 취약 버전으로 낮춰서 요청 응답을 주고받도록 유도하는 수법입니다. 이를 방지하려면 TLS의 최신 버전 사용을 강제하는 등 주의가 필요합니다.
공격은 어디서나 들어올 수 있기에 보안도 여러 군데에서 수행합니다. 예를 들면 HSTS (HTTP Strict Transport Security,"통신은 무조건 HTTPS로 해!")라는 규칙을 적용하기도 하고, 모던 브라우저들은 TLS_FALLBACK_SCSV (Signaling Cipher Suite Value, "억지로 낮은 보안 수준의 통신은 시도 금지") 라는 설정을 지원합니다. 다운그레이드 공격이 시도될 경우, 브라우저 측에서 연결을 거부하는 것이죠.
보안을 뚫는 창과 이를 막는 방패의 싸움은 끝이 없습니다. 우리는 여전히 보안이 뚫렸다는 뉴스를 많이 접합니다. 왜일까요?
독일 보안이 뚫린 이유
"에니그마"라는 단어를 한 번쯤은 들어보셨을 듯합니다. 그리스어로 "수수께끼"라는 뜻을 가진 에니그마는 2차 세계 대전 독일군이 쓰던 암호 체계였습니다.

에니그마는 어원에 어울릴 만큼 매우 복잡하고 정교했습니다. 에니그마를 통한 메시지를 해독하려면 150조 가지 이상의 케이스를 검증해야 했습니다.
150조는 2의 47제곱 미만으로 현대에선 성능 좋은 컴퓨터로 수 초만에 계산하는 정도입니다. 그러나 당시엔 해독이 절대로 불가능한 수준이었습니다. 그럼에도 에니그마는 결국 해독이 됐습니다. 어째서였을까요?
- 초기 에니그마의 매뉴얼이 들켰습니다.
- 일부 작전관은 매우 허술한 암호 키를 사용했습니다. 군대 컴퓨터 비밀번호처럼요.
- 주기마다 똑같은 암호 키를 반복 사용했습니다.
- 날씨 같은 잡담도 많이 주고 받느라 힌트가 새나갔습니다.
- 다른 암호 체계였던 METEO와 똑같은 설정을 사용했습니다.
- 실제로는 절대로 안 쓰이는 패턴들이 많이 발견돼 경우의 수가 확연히 줄었습니다.
그 외에도 수많은 실수들이 반복됐고, 에니그마는 끝내 해독됐습니다. 위의 원인들은 모두 단 하나의 사실을 공유합니다. "허술한 사용"입니다. 아무리 훌륭한 보안 체계를 갖춰도 사용자가 방심하면 보안은 무너진다는 교훈을 주는 일화입니다. 그 때문에 보안은 한 시도 긴장을 늦출 수 없는 문제입니다.
영국 항공의 데이터 유출
2018년 8월 경, British Airways는 대량의 고객 결제 데이터가 유출돼 2,700억의 벌금을 부과받았습니다. 폼 재킹(formjacking)이라는 수법의 보안 공격으로 당한 것이죠.

암호로 주고받는 것이 안전하다는 얘기는 그 과정이 정상일 때에만 가능합니다. 이 경우는 보안이 취약했던 British Airways가 해커에게 고객 정보를 바친 셈이죠.
쿠키
쿠키는 서버가 사용자를 식별하고 편리한 서비스를 제공하도록 돕는 인식표입니다.
- 서버는 최초로 방문한 사용자에게 쿠키를 발급합니다. 쿠키에는 사용자를 식별할 수 있는 고유한 정보와 여러 속성이 있습니다.
- 사용자는 쿠키를 받아서 이후에 사이트를 방문하거나 요청할 때마다 서버에게 쿠키를 보냅니다.
- 서버는 쿠키를 통해 사용자를 식별하고, 편리한 서비스를 제공합니다.
병원 서비스를 떠올려봅시다. 우리는 병원에 최초로 방문했을 때 개인 정보를 기입하고, 서비스를 이용합니다. 그 이후의 방문부터 내 신분만 인증하면 병원에서 내 진료기록과 정보를 찾아서 내게 맞춤 서비스를 제공하죠. 쿠키는 이와 같은 개념에서 출발한 아이디어입니다.
재방문한 사용자의 쿠키를 식별(세션 id)해서 자동 로그인을 돕거나, 스크립트로 쿠키가 탈취되는 것을 방지하고 HTTP 통신으로만 쿠키를 이용하도록 설정하거나(HttpOnly), HTTPS 환경에서만 쿠키를 이용하도록 설정하거나(secure), 서로 다른 도메인에서 요청하는 걸 방지(SameSite)하는 등 여러 속성이 있습니다.
쿠키는 탈취될 경우 위험하다는 이야기가 자주 회자됩니다만, 실제로는 곳곳에서 쿠키를 많이 쓰는 실정입니다. 어쨌든 매우 편리하기 때문이죠.
위에서 서술했듯, HTTPS를 통한 소통에선 쿠키도 암호화됩니다. 이 경우에는 쿠키가 탈취되더라도 현실적으로 쿠키 해독이 불가능합니다. 그래서 보통은 암호화가 안 된 로컬 쿠키를 노리거나, 사용자 권한을 이용해서 몰래 요청하므로 이에 대한 보안을 신경써야만 합니다.
CORS
Cross-Origin Resource Sharing의 줄임말로, 서로 다른 출처(Cross-Origin)에서의 자원 공유(Resource Sharing)에 대한 브라우저 정책입니다. 예컨대 네이버에서 미국 국방부로 보안 자료를 요청할 경우, 이런 걸 허용해선 안 됩니다.
본래 옛날엔 Same-Origin Policy이라고 해서, HTTP 요청은 같은 도메인일 때에만 허용했습니다. 그것이 보안에 좋으니까요. 그러나 웹이 발달하면서 한 페이지 내에 여러 회사의 서비스들(API 등)이 혼재하게 됩니다. 이에 대해 안전한 사용을 위해 CORS 정책이 나옵니다.
요약하자면 "안전한 출처끼리만 소통해라."입니다. 이를 위한 확인으로 프리플라이트(preflight) 요청이 있습니다.
브라우저는 서버에게 HTTP 메소드 중 하나인 OPTIONS 속성으로 요청을 보냅니다. 자신의 Origin이 서버에 안전하다고 등재됐는지 확인하죠. 서버 측에서 안전하다고 응답하면 브라우저는 그제서야 진짜 요청을 보내고 HTTP 소통을 개시합니다.
이를 통해 서버는 나쁜 코드가 침입하는 것을 방지합니다. 또한 클라이언트가 보안이 나쁜 사이트에서 정보를 도용당해 다른 사이트로 요청을 보내더라도, CORS 정책에 의해 차단되겠죠. CORS는 개발중에 많은 사람들을 피곤하게 만들기도 하지만 필수불가결인 정책입니다.
XSRF-TOKEN
XSRF-TOKEN은 쿠키와 CORS를 결합한 보안 아이디어입니다. CSRF(Cross-Site Request Forgery)는 사용자가 악성 사이트에 접속 시, 자기도 모르게 정상적인 사이트에 요청을 보내는 공격입니다.
XSRF-TOKEN은 브라우저 컨텍스트(세션 탭)마다 일시적으로 주어지는 쿠키로, 사용자는 요청마다 이 쿠키를 보내서 "정상적인 출처에서의 요청"인지 입증하게 됩니다. 해커가 악성 도메인에서 사용자로 하여금 요청을 보내게 시키면, XSRF-TOKEN이 없는 요청이 될 테고, 이는 정상적인 출처에서의 요청이 아니라며 거절당하겠죠.
참조
- Wikipedia. Onavo. https://en.wikipedia.org/wiki/Onavo
- haxlob(2024.04.14). How did Facebook intercept their competitor's encrypted mobile app traffic? https://doubleagent.net/onavo-facebook-ssl-mitm-technical-analysis/