홈페이지 취약점 분석 이야기 파일 지도 사진 깨알






>> 목록보이기
#쿠키 #Cookie #세션 #Session #세션쿠키 #HttpOnly #세션탈취 #XSS #취약점해설 #curl #FireBug

Session Cookie와 HttpOnly 이야기

쿠키(Cookie)는 웹 브라우저에 저장되는 데이타로 웹 서버에 사용자의 상태를 알려주는 역할을 한다. 예를 들어, "오늘 하루 이 창을 열지않음"과 같은 정보는 웹 브라우저의 쿠키로 처리할 수 있다. 만약 이를 서버에서 처리하려면 모든 접속자의 정보를 저장해야 하므로 비효율적이다. 때문에 쿠키라는 클라이언트 측 데이터 저장방식이 고안된 것이다.

쿠키는 웹 서버의 역할을 웹 브라우저가 일부 부담함으로써 웹서비스의 효율성을 매우 높일 수 있었다. 그런데 개인식별의 문제를 비연결지향성(connection-less) 규약인 HTTP로 구현하면서 보안문제가 발생하였다. SSH, FTP, telnet과 같은 연결지향형(connection-oriented) 통신은 한번 연결이 되면 한쪽에서 연결을 끊지않는 한 연결이 지속되며 서버-클라이언트는 서로간의 식별이 이루어지는 상태가 된다. 이를 세션(session)이라고 한다. HTTP에서는 쿠키를 이용하여 이러한 전통적인 세션을 흉내내게 되었다. 클라이언트에 저장되는 이 개인식별자 쿠키를 세션쿠키(Session Cookie), 세션ID(Session ID) 또는 간단하게 세션이라고 부른다.

세션쿠키를 이용한 개인식별 절차는 다음과 같이 나열해볼 수 있을 것이다.

  1. 웹 브라우저가 웹 서버에 접속한다.
  2. 웹 서버는 세션 ID(개인식별자)를 생성하여 웹 브라우저에게 전달하면 웹브라우저는 세션ID를 쿠키로 저장한다(세션쿠키).
  3. 웹 브라우저가 사용자 인증(로그인)을 한다. (웹 브라우저는 세션쿠키(세션ID)를 항상 웹서버에 전달)
  4. 웹 서버는 세션 ID로 접근할 수 있는 공간에 사용자정보를 저장한다(세션 데이터).
  5. 이후의 통신에서 클라이언트가 동일 세션쿠키를 전달하면 서버는 개인인증이 된 것로 취급한다.

문제는 HTTP가 연결지향성 통신이 아니라는 점이다. 서버와 클라이언트가 계속 연결된 상태가 아니므로, 웹서버는 웹브라우저가 전달하는 세션쿠키 값을 믿을 수 밖에 없다. 이 세션쿠키를 탈취할 수 있으면 탈취당한 이의 권한으로 해당 웹서비스에 접속할 수 있다. (이를 일부 완화할 수 있는 방법으로 "IP보안"이라는 개념을 일부 웹서비스에서 적용하고 있다.)

HTTP 세션 탈취 공격은 HTML 삽입 공격으로 자바스크립트(JavaScript)를 실행하여 이루어진다. 이를 크로스사이트스크립트(XSS, Cross-site Script) 공격이라고 한다. XSS 취약점이 있으면, 공격자는 자바스크립트로 피해자의 웹브라우저에 저장된 쿠키값을 읽어서 공격자에게 전송시키는 공격을 수행할 수 있다. 이 점에 착안하여 고안된 세션탈취 방어 방법이 "HttpOnly"이다.

HttpOnly라는 이름에서 알 수 있듯이 HttpOnly가 설정된 쿠키는 HTTP 통신 상에서만 사용되어야 한다는 선언이다. 즉, 통신에서만 사용되므로 자바스크립트 같은 외부 프로그램은 접근할 수 없도록해야 한다는 의미이다. Microsoft가 2002년에 MS Internet Explorer 6.0 SP1에 적용한 이후로 현재는 거의 모든 웹 브라우저가 지원한다.

curl을 이용한 HttpOnly 설정여부 점검

HttpOnly 설정 여부는 HTTP의 "Set-Cookie:" 헤더를 보면 알 수 있다. curl은 "-I" 옵션을 주면 접속하는 페이지의 헤더를 출력한다. 페이스북 첫 페이지의 HTTP 헤더를 살펴보자.

root@kali:~# curl -I https://www.facebook.com/
HTTP/1.1 200 OK
P3P: CP="Facebook does not have a P3P policy. Learn why here: http://fb.me/p3p"
Strict-Transport-Security: max-age=15552000; preload
Cache-Control: private, no-cache, no-store, must-revalidate
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Pragma: no-cache
public-key-pins-report-only: max-age=500; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E="; pin-sha256="q4PO2G2cbkZhZ82+JgmRUyGMoAeozA+BSXVXQWB8XWQ="; report-uri="http://reports.fb.com/hpkp/"
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
X-Frame-Options: DENY
Set-Cookie: fr=0KuulGRP9yfrGfPiZ..BYKlaM.Op.AAA.0.0.BYKlaM.AWWPnClQ; expires=Mon, 13-Feb-2017 00:27:56 GMT; Max-Age=7776000; path=/; domain=.facebook.com; httponly
Vary: Accept-Encoding
Content-Type: text/html
X-FB-Debug: te/VbRc/M4/3KICC68vojnxrSDWIGBk1dhCUqZKHGQ7RnHor0Aiw2hUP0FrkeYYt/a9ZMEXQy6ZqFgJNZUA4Qg==
Date: Tue, 15 Nov 2016 00:27:56 GMT
Connection: keep-alive

root@kali:~#

Set-Cookie: 헤더에서 fr 쿠키의 마지막에 httponly가 명시되어 있는 것을 볼 수 있다. 이 쿠키는 웹 브라우저가 HttpOnly로 설정되므로 자바스크립트 등이 접근하려고 하면 웹 브라우저가 차단한다.

또 다른 예로 이 홈페이지(webhack.dynu.net)의 HTTP헤더를 살펴보자.

root@kali:~# curl -I http://webhack.dynu.net/
HTTP/1.1 200 OK
Date: Tue, 15 Nov 2016 00:45:12 GMT
Server: Apache
Set-Cookie: NormalCookie=Not-HttpOnly-Cookie
Set-Cookie: HttpOnlyCookie=HttpOnly-Cookie; httponly
Content-Type: text/html; charset=UTF-8

root@kali:~#

두 개의 Set-Cookie:가 있으며 NormalCookieHttpOny가 선언되지 않았고, HttpOnlyCookieHttpOny가 선언된 것을 볼 수 있다. 다음 절에서 자바스크립트(JavaScript)가 이 두 쿠키에 대해서 어떻게 접근하는 지 시험해볼 수 있다.

자바스크립트의 HttpOnly 쿠키 접근여부 시험

FireFox에서는 FireBug라는 부가기능(Add-on)을 이용하여 HttpOnly 여부를 검사할 수 있다. 다음 그림은 파이어폭스로 이 누리집에 접근했을 때 Firebug가 보여주는 쿠키목록이다. 자바스크립트를 이용하여 HttpOnly 쿠키 접근 여부를 확인해보자.

Firebug를 이용한 쿠키 확인
[ FireFox에서 FireBug를 이용한 쿠키 정보 확인 ]

다음은 현재 이 누리집에서 설정된 모든 쿠키(Cookie)들이다.

두 개 이상의 쿠키가 보일 것이다. NormalCookie는 일반적인 쿠키이며, HttpOnlyCookieHttpOnly로 선언된 쿠키이다.

위의 메뉴를 클릭해보자 -- 클릭했을 때 JavaScript의 alert(document.cookie)가 실행된다. 자바스크립트의 alert() 창에서 HttpOnlyCookie=HttpOnly-Cookie는 보이지 않아야 한다. 이 값이 보인다면 HttpOnly를 지원하지 않는 웹 브라우저이다. Google Chrome, FireFox, Safari 등에서는 HttpOnlyCookie가 출력되지 않았다. 즉, 이들 브라우저는 HttpOnly를 지원한다.

이처럼 세션쿠키에 대해서 HttpOnly 설정이 되어 있으면 크로스사이트스크립트(XSS) 취약점이 있더라도 세션탈취만은 막을 수 있다. HttpOnly는 간단하고 효율적인 세션탈취 방어 방법이지만 궁극적인 XSS 방어법은 아니라는 점은 유의해야 한다.

HttpOnly 우회

HttpOnly를 이용한 세션탈취 방어도 우회할 방법이 소개된 바 있다. 소위 XST(Cross-site Tracing)이라는 공격법으로 TRACE 메소드가 허용되는 사이트에서 가능할 수 있다. 2003년에 Jeremiah Grossman이라는 보안전문가가 발표한 취약점이다. 이 방법은 AJAX를 이용하는 데, 다행히도 최근의 웹 브라우저에서는 AJAX에서 TRACE를 허용하지 않아서 성공하기 어려운 공격법으로 보인다. 다만, 확언할 수는 없지만, 플래쉬(Flash) 등과 같은 다른 방법으로 XST 공격이 성공할 수 있는 가능성은 있는 것으로 보인다.

[처음 작성한 날: 2016.11.10]    [마지막으로 고친 날: 2016.11.15] 


< 이전 글 : HTTP TRACE method와 XST 공격 (2016.11.11)

> 다음 글 : HTTP 메소드 수동점검 방법 (2016.11.10)


크리에이티브 커먼즈 라이선스 이 저작물은 크리에이티브 커먼즈 저작자표시 4.0 국제 라이선스에 따라 이용할 수 있습니다.
잘못된 내용, 오탈자 및 기타 문의사항은 j1n5uk{at}daum.net으로 연락주시기 바랍니다.
문서의 시작으로 컴퓨터 깨알지식 웹핵 누리집 대문