|
Dino Esposito
Wintellect
2005년 5월
요약: 쿠키를 사용하지 않는 세션의 리뷰와 세션 상태에 의미 있는 정보 저장을 피해야 하는 이유에 대한 토론
쿠키의 문제점은?
쿠키를 사용하지 않는 세션이란?
구현
이득
손실
요약
세션 상태의 아이디어에 많은 개발자들이 아주 익숙하게 알고 있습니다. 그러나 이 세션 상태는 1997년 ASP(Active Server Page)와 함께 소개된 오래된 기술입니다. 세션 상태는 여러분들에게 개발자로서 응용프로그램에서 사용자와 상호작용을 하는 동안 사용자에 대한 정보의 일부분을 지속할 수 있도록 해 줍니다. 특정 사용자 정보는 일반적으로 20분의 시간 동안 저장되고, 사용자가 사이트로 다시 돌아오는 경우에는 새롭게 갱신됩니다.
처음으로 사용자가 사이트에 접속하면 데이터를 가지면서 메모리의 블록 형식으로 새로운 세션 상태가 생성됩니다. 더불어 유일한 ID로 현재 사용자와 연결됩니다. 다음 요청이 발생하면 사용자는 현재의 세션 ID를 기다리게 되고, 세션 상태는 복구되게 됩니다. 세션 ID는 문자 숫자 조합으로 이루어지며 ASP와 ASP.NET에서 자동으로 생성됩니다. 어떻게 세션 상태로 사용자 관리와 다음 요청에서 상태를 유지 할 수 있을까요?
HTTP 프로토콜에서 상태를 저장하는 것에 대해 어느 누구도 이것을 변화하려고 시도를 하지 않았습니다. 거의 20년 전, Netscape에서 그들의 첫 번째 브라우저를 개발하는 동안에 HTTP를 통해 영속성의 메커니즘을 창안해내었습니다. 그들인 이를 HTTP 쿠키라 명명하였습니다. 이것은 매우 흥미로운 것으로서 "cookie"는 컴퓨터 과학 용어로 사용자들을 침범하는 프로그램에서의 데이터의 불분명한 조각을 대신하는 용어였지 결코 사용자에 의해 직접적으로 관리되는 의미가 있던 것은 아니었습니다.
쿠키는 세션의 ID를 저장하고 브라우저는 웹 서버와 로컬 사용자 컴퓨터로 그 내용을 주고 받게 되는 것입니다. 쿠키가 활성화된 브라우저는 응답 패킷을 먼저 수신하고, 패킷에서 쿠키가 첨부되었는지 검사한 다음 쿠키가 있는 경우 그 내용을 로컬 윈도우 디렉터리의 특정 폴더에 텍스트 파일로 저장하게 됩니다. 쿠키는 또한 출처 사이트의 정보도 가지고 있습니다. 그래서 다음에 브라우저가 특정 사이트로 요구(request)를 보내게 될 때 해당 도메인으로부터 생성된 쿠키들을 쿠키 폴더에서 찾게 됩니다. 만약 해당 쿠키가 발견된다면 그 쿠키는 자동적으로 패킷에 붙여서 전송되게 됩니다. 이렇게 서버로 보내진 쿠키는 서버 프로그램에 의해 쿠키의 내용을 인지하고, 인용하고, 처리하는데 사용하게 됩니다.
마지막으로 쿠키는 웹 사이트의 네비게이션을 쉽게 만들어줍니다. 여러 요청들에 필수적으로 거쳐야 하는 과정을 연속성을 지닌 쿠키를 사용자가 사용함으로 그 만큼의 시간의 이득을 주기 때문입니다.
몇 년 동안 쿠키는 그 이면의 문제점은 대부분 무시된 채 단순한 기술적인 요소로 인식되었습니다. 몇 년 전 월드와이드에서 웹 보안에 초점을 두게 되면서 쿠키가 주목을 끌게 되었습니다. 그들은 쿠키가 장비의 물리적인 경계를 넘어서 가치 있는 정보를 빼내는 능력이 있는 위험한 프로그램적 요소라고 주장하였습니다.
쿠키는 프로그램화 하지 않고서야 사용자의 개인 정보에 대해서 가져오고자 하더라도 쿠키 스스로 어떠한 정보도 수집할 수 없다는 것은 명백한 사실입니다. 보다 간단하게 쿠키는 웹 사이트가 사용자의 장치에 저장하고 이후에 조회하여 재사용할 수 있는 하나의 텍스트 파일에 불과합니다. 또한 쿠키에 저장되는 정보는 악의가 없는 이름과 값의 쌍으로 이루어져 있습니다.
다른 관점에서 쿠키는 표준 HTTP 명세의 부분이 아니며, 브라우저와 웹 사이트의 협업을 해야만 쿠키가 동작한다는 것을 내포하고 있습니다. 또한 모든 브라우저가 쿠키를 지원하는 것은 아니며, 더욱더 중요하게 생각해야 할 부분이 모든 사용자가 쿠키의 사용을 허용하고 있지 않는다는 것입니다.
웹 사이트의 특징들 중에 실제 해당 사용자가 처음 방문하였는지 구별하는 것은 쿠키의 유용함에 하나입니다. 또한 세션 상태 관리와 사용자 인증도 쿠키를 사용함으로 보다 쉬워집니다. 그리고 여러분들의 사이트에 접속하는 브라우저의 통계를 확인하고자 할 때에도 쿠키가 비활성화된 사용자 연결의 중요한 연결을 제공하는 것을 발견하고 놀라게 될 것입니다. 이것이 쿠키가 여러 문제점이 있지만 여러분들과 다른 많은 개발자들에게 주목을 끄는 점입니다.
요약하면 쿠키 자체로는 문제가 되지 않습니다. 그러나 쿠키를 사용하려면 클라이언트 장치에 데이터를 저장할 수 있도록 서버코드를 작성하여야만 쿠키를 사용할 수 있습니다. 그러므로 몇몇 잠재적인 보안의 위험과 쿠키가 가진 이점에 비해 전체적으로 상황이 안 좋게 보이는 것입니다. (몇몇 사례들에 의해 일부 국가에서는 프로그램에서 쿠키를 요구하여 작업하는 것이 불법으로 간주되고 있습니다.)
ASP.NET에서는 세션과 사용자의 연결에 선택적으로 쿠키를 사용하지 않을 수 있습니다. 이것은 상당히 흥미로운 사실로서 다음의 환경설정 부분을 제외하고 여러분들이 작성한 ASP.NET 응용프로그램의 나머지에서 어떠한 수정을 하지 않고서 쿠키를 사용하지 않는 세션을 활성화할 수 있습니다.
<sessionState cookieless="true" />
ASP.NET 세션 상태의 기본 설정은 machine.config 파일에 정의되어 있으며 해당 응용프로그램의 루트 폴더의 web.config 파일을 이용하여 재정의할 수 있습니다. 앞의 옵션을 루트 web.config 파일에 적용하면, 여러분들은 쿠키를 사용하지 않는 세션을 활성화할 수 있습니다. 간단한 옵션의 변경으로 설정을 변경하는 것입니다.
<sessionState>노드(node)에는 cookieless 옵션 이외의 저장 매체와 연결 문자열을 추가하여 세션 상태 관리의 다른 설정에도 사용할 수 있습니다. 그러나 쿠키가 관계 되는 경우라면 cookieless 특성을 true(기본 값은 false)로 설정하는 것을 우선시 해야 합니다.
세션 설정은 응용프로그램의 광범위한 설정이라는 것을 주의하시기 바랍니다. 다른 말로 여러분들의 사이트의 모든 페이지에서 세션 ID들을 저장하는데 쿠키를 사용하거나 하지 않을 수 있는 것을 변경하는 설정인 것입니다.
ASP.NET에서 세션 ID를 저장할 때 정말 쿠키가 사용되지 않을까요? 쿠키를 사용하지 않는 세션에서는 세션 ID가 URL 안에 특정한 위치에 삽입됩니다. 다음 그림은 실제 사이트에서 쿠키를 사용하지 않는 세션을 적용한 예제입니다.
그림 1. 쿠키를 사용하지 않는 세션이 적용된 MapPoint
여러분이 http://yourserver/folder/default.aspx 페이지 링크를 요청하는 상황을 생각해 보십시오. 위의 그림에서처럼 쿠키를 사용하지 않는 세션이 적용된 페이지에 접근하면 다음처럼 즉시 세션 ID가 주소에 확장되어 표시됩니다.
http://yourserver/folder/(session ID here)/default.aspx
앞에서 보는 것처럼 세션 ID는 URL에 내장되어 있으며 세션 ID 유지를 위해 특정 값을 저장하거나 다른 작업을 하는 것은 필요하지 않습니다. 과연 이것이 정확한 것일까요? 다음의 시나리오를 생각해 봅시다.
여러분이 페이지에 방문하고 세션 ID를 하나 할당 받습니다. 그런 다음 여러분들은 주소 입력창을 지운 후 동일한 브라우저를 사용하여 다른 사이트의 주소를 입력하여 이동하여 봅니다. 그런 다음 이전 사이트의 주소를 다시 입력하여 봅시다. 이전에 사용한 여러분의 세션 값을 다시 얻을 수 있습니다.
만약 여러분이 쿠키를 사용하지 않는 세션을 이용하는 경우라면 사이트로 재 접속할 때에는 다른 세션 ID가 할당되어야 하고, 이전의 상태 정보를 잃어버려야 한다고 생각할 수 있습니다. 이것이 전형적인 쿠키를 사용하지 않는 세션의 현상이라고 생각할 수 있습니다. 그러나 앞에서처럼 결과는 우리의 예상을 완전히 빗나갔습니다. 이것의 이해를 위해 쿠키를 사용하지 않는 세션의 구현을 통해 좀더 깊이 있게 살펴보도록 합시다.
쿠키를 사용하지 않는 세션의 구현은 두 개의 런타임 모듈의 실행으로부터 나오는 결과입니다. SessionStateModule로 이름 지어져 있는 표준 세션 HTTP 모듈과 실행에 알려진 aspnet_filter.dll이 그것들입니다. Dll 파일은 Win32 코드의 작은 부분으로 ISAPI 필터로 동작합니다. HTTP 모듈과 ISAPI 필터는 HTTP 모듈이 관리(managed)되는 코드로부터 제작되었고, 실행에 ASP.NET과 CLR이 필요하다는 것을 제외하고 동일한 아이디어를 구현하고 있습니다. 이전의 ISAPI 필터는 aspnet_filter.dll처럼 IIS(Internet Information Server)에 의해 실행됩니다. 그리고 요청(request)를 처리하는 동안 모두 IIS 이벤트로 인식되어 버립니다.
새 브라우저 세션의 요청이 처음으로 접근할 때 세션 상태 모듈은 web.config 파일에서 쿠키 지원에 대한 설정을 읽습니다. 만약 <sessionState> 섹션의 cookieless 특성이 true로 설정되어 있다면 모듈은 새로운 세션 ID를 생성하고, 리소스 페이지 이름 이전 부분의 URL을 분리하여 세션 ID를 채우고, HTTP 302 커멘드를 사용하여 새로운 URL로 브라우저를 리디렉션하게 됩니다.
각 요청이 IIS 진입점으로 도착하여 ASP.NET으로 넘어가기 전에 aspnet_filter.dll은 해당 요청을 검사하게 됩니다. 만일 URL에 세션 ID가 포함되어 있다면 세션 ID는 추출되어 AspFilterSessionId의 이름의 헤더로 복사됩니다. 이때 ASP.NET 세션 상태 모듈은 요청 헤더와 세션 상태로부터 세션 ID를 검색하고 세션 상태 바인딩으로 진행됩니다.
쿠키를 사용하지 않는(cookieless) 메커니즘은 URL에 세션 ID의 정보를 가지고 있는 동안 훌륭하게 동작합니다. 그러나 잠시 뒤에 살펴보겠지만 이것은 몇 가지 제한이 있습니다.
지금부터 쿠키를 사용하지 않는 세션의 득과 실에 대해서 알아보도록 합시다.
ASP.NET에서 세션 관리와 폼 인증은 쿠키 환경하에서 사용할 수 있는 시스템의 하나입니다. 쿠키를 사용하지 않는 세션을 이용한다면 여러분들은 사용자들의 쿠키에 대한 설정에 상관없이 동작하는 응용프로그램을 바로 배포할 수 있습니다. ASP.NET 1.x에서도 쿠키는 여전히 폼 인증을 구현하는데 사용되고 있습니다. 한가지 좋은 소식은 ASP.NET 2.0의 폼 인증에서는 선택적으로 cookieless 설정을 사용할 수 있다는 것입니다.
다른 이유로는 쿠키는 보안에 위험을 가지다 줄 수 있는 잠재 요소가 있다는 것입니다. 이점이 우리들이 주의해서 봐야 할 부분입니다.
쿠키는 텍스트 파일에 삽입됩니다. 그러나 이 쿠키 파일이 교체되거나 해커에 의해 악용되어 컴퓨터에 접속 하는 상황까지 발생합니다. 이것은 실제 위험 상태에 놓이게 되는 것을 의미합니다. 쿠키가 여러분들의 클라이언트 컴퓨터에 설치되는 것이지만 실제 서버 또는 대상 사이트로 업로드 할 수 있습니다. 그러나 쿠키는 프로그램화 되지 않고서는 결코 프로그램처럼 동작하지 않습니다. 여러분들의 컴퓨터에 설치되는 다른 소프트웨어와는 다르며 내장된 브라우저가 쿠키를 지원할 때에만 해가 되는 작업을 원격에서 처리할 수 있습니다.
게다가 쿠키는 정보유출의 위험성을 가지고 있습니다. 의미 있는 개인 정보를 가지는 쿠키를 악의의 해커에 의해 쿠키의 내용이 유출될 수 있고 웹 공격의 다른 유형으로 사용될 수 있습니다. 요약하면 쿠키를 사용하는 것은 여러분들이 스스로를 위험에 노출시키는 행위가 되는 것입니다. 그러므로 쿠키를 사용하지 않는 세션을 사용하게 된다면 이런 위험이 사라지게 되는 것입니다. 정말로 그런가요?
다른 견지의 보안을 살펴보도록 합시다. 여러분들은 세션 하이제킹(hijacking)에 대해 들어 본적이 있습니까? 만약 없다면 TechNet 매거진의 다음 기사 (Theft On The Web: Prevent Session Hijacking (영문))를 살펴보도록 합시다. 세션 하이제킹은 공격자(attacker)가 특정 사용자의 세션 상태에 접근을 얻고자 할 때 발생하는 것입니다. 원래 공격자는 유용한 세션 ID를 훔쳐서 시스템에 침입하는데 사용하거나 데이터의 수집을 하는 것이 일반적입니다. 일반적으로 유효한 세션 ID를 얻었다면 유효한 세션 쿠키를 훔치게 되는 것입니다. 즉 만약 여러분들이 응용프로그램에 보안적인 측면을 생각하여 쿠키를 사용하지 않는 세션을 생각하는 것이라면 그것은 아주 잘못된 생각입니다. 쿠키를 사용하지 않는 세션을 사용한다는 것은 세션 ID를 주소 창에 보여주는 것이기 때문입니다. 다음을 따라 해 봅시다:
이처럼 쿠키를 사용하지 않는 세션을 사용한다면 세션 ID를 획득하는 것이 훨씬 쉬워집니다.
세션을 훔치는 것은 윤리적인 관점에서 비난 받을 행위라고 모두 동의할 것입니다. 또한 그것이 부정한 것임을 알고 있습니다. 그러나 이런 행위를 막는 것은 실제로 세션 상태의 저장에 달려 있습니다. 훔친 세션 ID는 본질적으로 코드 제어의 외부에서는 실행되지 않습니다. 그러나 인증 받지 않은 사용자에게 개인 데이터를 노출할 수 있고 인증 받지 않은 기능을 실행할 수 있습니다. ASP.NET 어플리케이션에서의 세션 훔침을 어떻게 방어하는지에 대한 팁이 나온 다음의 기사 (Wicked Code: Foiling Session Hijacking Attempts (영문)) 를 읽어봅시다.
쿠키를 사용하지 않는 세션을 이용하는 것은 연결에 문제를 발생시킵니다. 예를 들어 여러분의 ASP.NET 페이지에서 절대 경로(전체 사이트의 URL)의 링크를 가지는 경우입니다. 만약 여러분이 이것을 사용하고자 한다면 하이퍼링크는 각 요청을 새로운 세션의 일부로 인식하게 되어 새롭게 시작하게 될 것입니다. 쿠키를 사용하지 않는 세션은 항상 세션 ID와 연관된 URL을 사용해야 하고, ASP.NET에 의해 게시되어 연결됩니다. 만약 URL에 세션 ID를 포함할 수 있다면 여러분들은 권한을 할당 받아 사이트를 이용할 수 있습니다. 그러나 그렇게 수행하고자 하는 경우에 세션 ID들은 런타임에 생성되는 것인가요?
다음의 코드는 세션을 중지하는 것입니다:
<a runat="server" href="/test/page.aspx">Click</a>
HttpResponse 클래스의 ApplyAppPathModifier메서드를 사용하여 절대경로 URL로 변경되도록 수정하여 봅시다:
<a runat="server" href=<% =Response.ApplyAppPathModifier("/test/page.aspx")%> >Click</a>
ApplyAppPathModifier 메서드는 URL의 문자를 표시하는 것으로 세션 정보가 내장된 절대 URL 경로를 반환합니다. 예를 들어 이 트릭은 HTTP 페이지에서 HTTPS 페이지로 리디렉션이 필요한 경우에 특히 유용하게 사용할 수 있습니다. 결국 매번 여러분들이 동일 브라우저 안에서 사이트의 경로를 입력하더라도 쿠키를 사용하지 않는 세션은 여러분들의 상태를 잃어버린다는 것을 알게 될 것입니다. 게다가 쿠키를 사용하지 않는 세션은 모바일 응용프로그램에서 만약 특정 유형의 URL을 처리하지 못하거나 상대경로를 처리하지 못할 때 문제를 발생시킬 수 있음을 주의를 해야 합니다.
ASP.NET에서 쿠키를 사용하지 않는 세션을 이용하는 주된 이유는 사용자들의 브라우저에서 쿠키를 비활성화한 것에 대응하기 위한 것입니다. 좋든 싫든 이것은 세션 상태를 필요로 여러분들의 응용프로그램이 직면한 상황입니다. 쿠키를 사용하지 않는 세션은 URL에서 세션 ID가 내장되어 있고, 여기에는 득과 실이 있습니다. 사용자 요청의 유일함이 정확한 것인지를 웹 사이트에 제공하는 것이 득인 반면에, 세션 ID를 쉽게 훔치고 정보를 유출할 수 있는 잠재적인 해커에게 명확하게 세션 ID를 보여주게 되는 것이 실이 됩니다.
쿠키를 사용하지 않는 세션을 구현할 때에는 여러분들이 작성한 프로그래밍 모델을 수정할 필요 없이 간단히 web.config 파일을 수정하는 것으로 사이트에 반영할 수 있습니다. 그러나 여러분들의 어플리케이션에서 세션 상태에 의미 있는 정보 저장을 피하고자 할 때 추천되는 방법입니다. 똑같은 의미로 세션의 활성화 시간을 기본 20분보다 줄이고자 할 때 사용자들을 유지하고 사이트를 안전하게 하는데 도움을 주는 것입니다.