인터넷이라는 거대한 관을 통해 흐르는 개인 정보의 양을 고려할 때 암호화는 가볍게 무시할 수 있는 사안이 아닙니다. 최신 브라우저는 전송 중인 사용자 데이터의 보안을 유지하는 데 사용할 수 있는 여러 메커니즘을 제공합니다. 그중 가장 중요한 것은 안전한 쿠키와 엄격한 전송 보안입니다. 이를 통해 사용자를 원활하게 보호하고, 연결을 HTTPS로 업그레이드하며, 사용자 데이터가 일반 텍스트로 전송되지 않도록 보장할 수 있습니다.
왜 관심을 가져야 할까요? 다음을 고려하세요.
암호화되지 않은 HTTP 연결을 통해 웹페이지를 전송하는 것은 우체국 방향으로 걸어가는 것처럼 보이는 거리에서 처음 만난 사람에게 봉인되지 않은 봉투를 건네는 것과 거의 같습니다. 운이 좋으면 배송업체에서 직접 배송하거나 올바른 방향으로 이동하는 다음 사람에게 전달할 수도 있습니다. 그 사람이 나를 차단할 수도 있고,
이 즉석 체인의 대부분의 낯선 사람은 신뢰할 수 있으며 공개서한을 엿보거나 변경하지 않습니다. 하지만 편지가 여러 사람의 손을 거칠수록 보내는 편지에 대한 전체 액세스 권한이 있는 사람이 많아집니다. 결국 편지의 대상 수신자가 우편으로 무언가를 받게 될 가능성이 높지만, 그 무언가가 처음에 전달한 것과 동일한 것인지는 알 수 없습니다. 봉투를 봉인했어야 했는데...
중개인
좋든 싫든 인터넷의 상당 부분은 낯선 사람의 신뢰성에 의존합니다. 서버는 서로 직접 연결되지는 않지만 거대한 텔레폰 게임에서 라우터에서 라우터로 요청과 응답을 전달합니다.
traceroute를 사용하여 이러한 홉이 작동하는 모습을 확인할 수 있습니다. 컴퓨터에서 HTML5Rocks로의 경로는 다음과 같습니다.
$ traceroute html5rocks.com
traceroute to html5rocks.com (173.194.71.102), 30 hops max, 60 byte packets
1 router1-lon.linode.com (212.111.33.229) 0.453 ms
2 212.111.33.233 (212.111.33.233) 1.067 ms
3 217.20.44.194 (217.20.44.194) 0.704 ms
4 google1.lonap.net (193.203.5.136) 0.804 ms
5 209.85.255.76 (209.85.255.76) 0.925 ms
6 209.85.253.94 (209.85.253.94) 1.226 ms
7 209.85.240.28 (209.85.240.28) 48.714 ms
8 216.239.47.12 (216.239.47.12) 22.575 ms
9 209.85.241.193 (209.85.241.193) 36.033 ms
10 72.14.233.180 (72.14.233.180) 43.222 ms
11 72.14.233.170 (72.14.233.170) 43.242 ms
12 *
13 lb-in-f102.1e100.net (173.194.71.102) 44.523 ms
13홉은 나쁘지 않습니다. 하지만 HTTP를 통해 요청을 전송하는 경우 이러한 중간 라우터 각각은 내 요청과 서버의 응답에 완전히 액세스할 수 있습니다. 모든 데이터가 암호화되지 않은 일반 텍스트로 전송되며 이러한 중개자는 미들맨 역할을 하여 내 데이터를 읽거나 전송 중에 조작할 수도 있습니다.
더 나쁜 것은 이러한 종류의 가로채기는 거의 감지할 수 없다는 점입니다. 수신된 데이터가 전송된 데이터와 _정확히_ 동일한지 확인할 수 있는 메커니즘이 없으므로 악의적으로 수정된 HTTP 응답은 유효한 응답과 정확히 동일하게 보입니다. 누군가 재미로 내 인터넷을 뒤집어엎으려고 한다면 그때는 어쩔 수 없습니다.
보안 라인인가요?
일반 텍스트 HTTP에서 보안 처리된 HTTPS 연결로 전환하면 중개인으로부터 가장 효과적으로 방어할 수 있습니다. HTTPS 연결은 데이터가 전송되기 전에 전체 채널을 엔드 투 엔드로 암호화하므로 사용자와 대상 간에 있는 머신이 전송 중인 데이터를 읽거나 수정할 수 없습니다.

HTTPS가 제공하는 보안은 공개 키와 비공개 키의 개념에 기반합니다. 세부사항에 대한 심층적인 논의는 (다행스럽게도) 이 도움말의 범위를 벗어나지만 핵심 전제는 매우 간단합니다. 지정된 공개 키로 암호화된 데이터는 해당 비공개 키로만 복호화할 수 있습니다. 브라우저가 보안 채널을 만들기 위해 HTTPS 핸드셰이크를 시작하면 서버는 서버에 적절한 비공개 키가 있는지 확인하여 브라우저의 ID를 확인하는 데 필요한 모든 정보를 제공하는 인증서를 제공합니다. 이 시점 이후의 모든 통신은 요청이 인증된 서버로 전송되고 응답이 인증된 서버에서 수신되었음을 증명하는 방식으로 암호화됩니다.
따라서 HTTPS를 사용하면 내가 생각하는 서버와 통신하고 있고 다른 사람이 도청하거나 전송 중인 비트를 조작하고 있지 않다는 것을 어느 정도 확신할 수 있습니다. 이러한 종류의 암호화는 웹 보안을 위한 절대적인 기본 요건입니다. 현재 애플리케이션이 HTTPS를 통해 제공되지 않으면 공격에 취약합니다. 문제를 해결하세요. Ars Technica에 인증서를 무료로 가져오고 설치하는 방법에 관한 가이드가 있으니 기술적 세부정보를 확인해 보시기 바랍니다. 구성은 제공업체마다, 서버마다 다르지만 인증서 요청 프로세스는 어디서나 동일합니다.
보안은 기본
인증서를 요청하고 설치한 후에는 사용자가 이러한 노력의 혜택을 누릴 수 있도록 하세요. HTTP 리디렉션의 마법을 통해 기존 사용자를 HTTPS 연결로 투명하게 이전하고 쿠키가 보안 연결을 통해서만 전송되도록 합니다.
이쪽으로
사용자가 http://example.com/
를 방문하면 적절한 Location
헤더가 있는 301 Moved
Permanently
응답을 전송하여 https://example.com/
로 리디렉션합니다.
$ curl -I http://mkw.st/
HTTP/1.1 301 Moved Permanently
Server: nginx/1.3.7
...
Keep-Alive: timeout=20
Location: https://mkw.st/
Apache 또는 Nginx와 같은 서버에서 이러한 종류의 리디렉션을 쉽게 설정할 수 있습니다.
예를 들어 http://example.com/
에서 https://example.com/
로 리디렉션하는 Nginx 구성은 다음과 같습니다.
server {
listen [YOUR IP ADDRESS HERE]:80;
server_name example.com www.example.com;
location "/" {
rewrite ^(.*) https://www.example.com$1 permanent;
}
}
쿠키 저장소 잠그기
쿠키를 사용하면 스테이트리스 HTTP 프로토콜을 통해 사용자에게 원활한 로그인 환경을 제공할 수 있습니다. 세션 ID와 같은 민감한 정보를 비롯하여 쿠키에 저장된 데이터는 모든 요청과 함께 전송되므로 서버는 현재 응답 중인 사용자를 파악할 수 있습니다. 사용자가 HTTPS를 통해 사이트에 연결되었는지 확인한 후에는 쿠키에 저장된 민감한 정보가 안전한 연결을 통해서만 전송되고 암호화되지 않은 상태로 전송되지 않도록 해야 합니다.
쿠키를 설정할 때는 일반적으로 다음과 같은 HTTP 헤더가 사용됩니다.
set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT
단일 키워드를 추가하여 브라우저에 세션을 보호하기 위해 쿠키 사용을 제한하도록 지시할 수 있습니다.
Set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT; secure
secure 키워드로 설정된 쿠키는 HTTP를 통해 전송되지 않습니다.
열려 있는 창 닫기
HTTPS로의 투명 리디렉션은 사용자가 사이트에 있는 대부분의 시간 동안 안전한 연결을 사용한다는 것을 의미합니다. 하지만 공격 기회가 약간 있습니다. 초기 HTTP 연결은 완전히 열려 있어 SSL 제거 및 관련 공격에 취약합니다. 중간자 공격자는 초기 HTTP 요청에 대한 완전한 액세스 권한이 있으므로 사용자와 서버 간의 프록시 역할을 하여 서버의 의도와 관계없이 안전하지 않은 HTTP 연결을 유지할 수 있습니다.
브라우저에 HTTP Strict Transport Security(HSTS)를 적용하도록 요청하여 이러한 유형의 공격 위험을 완화할 수 있습니다. Strict-Transport-Security
HTTP 헤더를 전송하면 브라우저가 네트워크를 건드리지 않고 HTTP에서 HTTPS로 리디렉션을 클라이언트 측에서 실행하도록 지시합니다. 이는 성능에도 좋습니다. 요청을 하지 않는 것이 가장 좋은 요청입니다.
$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000
이 헤더를 지원하는 브라우저 (현재 Firefox, Chrome, Opera: caniuse에 세부정보 있음)는 이 특정 사이트에서 HTTPS 전용 액세스를 요청했음을 기록합니다. 즉, 사용자가 사이트에 접속하는 방법과 관계없이 HTTPS를 통해 사이트를 방문하게 됩니다. 브라우저에 http://example.com/을 입력하더라도 HTTP 연결을 설정하지 않고도 HTTPS로 연결됩니다. 더 좋은 점은 브라우저에서 잘못된 인증서를 감지하면 (서버의 ID를 스푸핑하려고 할 수 있음) 사용자가 HTTP를 통해 계속 진행할 수 없다는 것입니다. 좋든 나쁘든 전부 아니면 전혀 없음입니다.
브라우저는 max-age
초(이 예에서는 약 한 달) 후에 서버의 HSTS 상태를 만료합니다. 이 값을 적당히 높게 설정하세요.
헤더에 includeSubDomains
지시어를 추가하여 출처의 모든 하위 도메인이 보호되도록 할 수도 있습니다.
$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000
안전하게 진행하세요
전송하는 데이터가 의도한 수신자에게 온전히 도착하는지 확인할 수 있는 유일한 방법은 HTTPS를 사용하는 것입니다. 지금 바로 사이트와 애플리케이션에 보안 연결을 설정해야 합니다. 이 과정은 매우 간단하며 고객의 데이터를 안전하게 보호하는 데 도움이 됩니다. 암호화된 채널을 설정한 후에는 301 HTTP 응답을 전송하여 사용자가 사이트에 도달한 경로와 관계없이 사용자를 이 보안 연결로 투명하게 리디렉션해야 합니다. 그런 다음 쿠키를 설정할 때 secure 키워드를 추가하여 모든 사용자의 민감한 세션 정보가 해당 보안 연결을 만 사용하도록 합니다.
이 작업을 모두 완료한 후에는 사용자가 실수로 연결이 끊어지지 않도록 합니다. 브라우저가 Strict-Transport-Security
헤더를 전송하여 올바르게 작동하도록 하여 사용자를 보호합니다.
HTTPS를 설정하는 작업은 어렵지 않으며 사이트와 사용자에게 큰 이점을 제공합니다. 노력한 만큼 보람이 있습니다.
리소스
- StartSSL은 무료 도메인 인증 인증서를 제공합니다. 무료는 이길 수 없습니다. 물론 더 높은 등급의 인증을 받으실 수 있으며 가격도 합리적입니다.
- SSL 서버 테스트: 서버에 HTTPS를 설정한 후 SSL Labs의 서버 테스트를 통해 올바르게 설정했는지 확인합니다. 실제로 실행 중인지 여부를 보여주는 상세한 보고서를 받게 됩니다.
- 서버 설정의 기본사항에 관한 자세한 배경 정보를 확인하려면 Ars Technica의 최근 도움말인 'SSL/TLS로 웹 서버 보호하기'를 참고하세요.
- HTTP Strict Transport Security 사양(RFC6797)에서 필요한
Strict-Transport-Security
헤더에 관한 모든 기술 정보를 훑어보는 것이 좋습니다. - 어떤 작업을 하고 있는지 확실히 알게 되면 다음 단계로 사이트에 특정 인증서 세트를 통해서만 연결할 수 있다고 광고할 수 있습니다. IETF에서
Public-Key-Pins
헤더를 통해 바로 이 작업을 할 수 있는 작업을 진행하고 있습니다. 아직 초기 단계이지만 흥미롭고 주목할 만한 작업입니다.