세션 고정
Session fixation![]() |
컴퓨터 네트워크 보안에서 세션 고정 공격은 한 사람이 다른 사람의 세션 식별자를 고정(찾거나 설정)할 수 있는 시스템의 취약성을 이용하려고 시도한다.대부분의 세션 고정 공격은 웹 기반이며, 대부분은 URL(쿼리 문자열) 또는 POST 데이터에서 수신되는 세션 식별자에 의존한다.null
공격 시나리오
앨리스는 은행에 계좌를 가지고 있다.http://unsafe.example.com/
말로리는 은행에서 앨리스의 돈을 노리고 있다.null
앨리스는 말로리에 대해 합리적인 수준의 신뢰를 가지고 있으며 말로리가 그녀에게 보내는 링크를 방문할 것이다.null
간단한 공격 시나리오
간단한 시나리오:
- 말로리는 다음과 같이 결정했다.
http://unsafe.example.com/
세션 식별자를 수락하고, 쿼리 문자열에서 세션 식별자를 수락하며, 보안 유효성 검사가 없다.nullhttp://unsafe.example.com/
따라서 안전하지 않다. - 말로리는 앨리스에게 이메일을 보낸다: "야, 이것 좀 봐, 우리 은행에 멋진 새로운 계좌 요약 기능이 있어.
http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SID
". 말로리는 SID를 에 고정시키려 하고 있다.I_WILL_KNOW_THE_SID
. - 앨리스는 관심이 많고 방문한다.
http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SID
.평소 로그온 화면이 뜨면 앨리스가 로그온한다. - 말로리 방문
http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SID
이제 앨리스의 계좌에 무제한으로 접근할 수 있게 되었다.
서버 생성 SID를 사용한 공격
서버가 서버 생성 세션 식별자만 받아들인다면 고정으로부터 안전하다는 잘못된 생각이다.이것은 거짓이다.null
시나리오:
- 말로리 방문
http://vulnerable.example.com/
그리고 어떤 SID가 반환되는지 확인한다.예를 들어, 서버는 다음과 같이 응답할 수 있다.Set-Cookie: SID=0D6441FEA4496C2
. - 말로리는 이제 앨리스에게 이메일을 보낼 수 있다: "우리 은행의 새로운 멋진 기능을 확인해봐.
http://vulnerable.example.com/?SID=0D6441FEA4496C2
." - 앨리스 로그온(고정 세션 식별자 포함)
SID=0D6441FEA4496C2
. - 말로리 방문
http://vulnerable.example.com/?SID=0D6441FEA4496C2
이제 앨리스의 계좌에 무제한으로 접근할 수 있게 되었다.
교차 도메인 쿠키를 사용한 공격
이러한 유형의 공격은 사용자 브라우저의 취약성에 의존하지 않는다는 점을 제외하면 교차 사이트 쿠키 공격과 유사하다.오히려 와일드카드 쿠키는 하위 도메인에 의해 설정될 수 있고, 그러한 쿠키는 다른 하위 도메인에 영향을 미칠 수 있다는 사실에 의존한다.null
시나리오:
- 웹 사이트
www.example.com
신뢰할 수 없는 제3자에게 서브돔을 나누어 주다. - 그런 파티 중 하나인 말로리는 이제 지배하고 있다.
evil.example.com
앨리스를 그의 사이트로 유인한다. - 에의 방문.
evil.example.com
도메인과 세션 쿠키 설정.example.com
앨리스의 브라우저로 - 앨리스가 방문할 때
www.example.com
이 쿠키는 요청과 함께 보내질 것이고 앨리스는 말로리의 쿠키가 지정한 세션을 가질 것이다. - 앨리스가 지금 접속하면 말로리는 그녀의 계정을 사용할 수 있다.
이 공격이 완료되면 말로리는 에 접근할 수 있다.www.example.com
앨리스로null
세션 고정 공격을[1] 이용하기 위해 사용자 로그인이 반드시 필요한 것은 아니며, 이러한 인증되지 않은 공격은 하위 도메인 간 쿠키 공격에 제약을 받지 않지만 하위 도메인 공격의 의미는 이러한 인증되지 않은 시나리오와 관련이 있다.예를 들어 말로리는 악의적인 사이트의 URL을 제공하여 세션을 인증되지 않은 시나리오로 고정하고 이러한 기술을 사용하여 목표를 이용할 수 있다.여기에는 인증되지 않은 시나리오(예: 양식 또는 등록)를 모두 활용하는 시나리오와 로그인을 완전히 우회하기 위해 설정된 세션을 사용자에게 제공하는 기능이 포함된다.null
예를 들어 말로리가 www.example.com에 사용자 A1ice를 생성하고 해당 사용자에게 로그인하여 현재 유효한 세션 식별자를 캡처할 수 있다는 점을 고려해 보십시오.그런 다음 말로리는 앨리스의 브라우저에 세션 쿠키를 고정하는 evil.example.com의 URL로 앨리스를 사로잡고 특정 거래를 마무리짓기 위해 www.example.com으로 리디렉션한다.따라서 말로리는 'www.example.com'에서 원래 로그인, 데이터 스크래핑 및 운영 실행에서 'A1ice'로 세션을 종료할 수 있다.만약 앨리스가 성공적으로 속아서 신용카드를 계좌에 저장했다면, 말로리는 그 카드를 사용하여 구매를 할 수 있을 것이다.null
대응책
GET/POST 변수에서 세션 식별자를 허용하지 않음
URL(쿼리 문자열, GET 변수) 또는 POST 변수의 세션 식별자는 이 공격을 단순화하기 때문에 권장하지 않는다. GET/POST 변수를 설정하는 링크나 형식을 쉽게 만들 수 있다.null
- 사용자가 주소 표시줄에서 "즐거운 링크"를 채팅, 포럼, 커뮤니티 등에 잘라 붙여넣기 때문에 SID는 다른 사람에게 유출된다.
- SID는 여러 곳에 저장된다(브라우저 기록 로그, 웹 서버 로그, 프록시 로그 등).
참고: 쿠키는 탭과 팝업 브라우저 창 사이에서 공유된다.시스템이 동일한 도메인(www.example.com/?code=site1 및 www.example.com/?code=site2 )으로 히트해야 하는 경우, 쿠키는 탭 간에 서로 충돌할 수 있다.null
이러한 한계를 극복하기 위해 URL에 세션 식별자를 전송해야 할 수도 있다.가능하면 쿠키에 도메인 충돌이 없도록 site2.example.com 또는 site1.example.com을 사용하십시오.이는 추가 SSL 인증서로 비용이 발생할 수 있다.null
이러한 행동은 다른 탭을 열고 검색 결과를 나란히 시도함으로써 많은 사이트에서 볼 수 있다.세션 중 하나를 사용할 수 없게 된다.null
최상의 솔루션:신원확인
사용자가 로그인할 때 세션 ID를 변경하면 이 공격을 크게 피할 수 있다.사용자에게 특정된 모든 요청이 사이트를 인증("로그인")해야 하는 경우 공격자는 공격 대상자의 로그인 세션 ID를 알아야 한다.그러나 피해자가 고정된 세션 ID로 링크를 방문했을 때, 그들 자신처럼 "중요한" 일을 하기 위해서는 그들의 계정에 로그인해야 할 것이다.이때 이들의 세션 ID는 바뀌게 되며, 공격자는 익명의 세션 ID로 '중요한' 일을 할 수 없게 된다.null
피싱 문제를 해결하기 위해 유사한 기술을 사용할 수 있다.사용자가 두 개의 비밀번호로 자신의 계정을 보호한다면, 그것은 크게 해결될 수 있다.null
이 기술은 사이트 간 요청 위조 공격에도 유용하다.null
해결책:HTTP 쿠키에 세션 식별자 저장
대부분의 최신 시스템의 세션 식별자는 기본적으로 HTTP 쿠키에 저장되며, 이는 세션 시스템이 GET/POST 값을 무시하는 한 중간 수준의 보안을 가지고 있다.[citation needed]그러나 이 솔루션은 사이트 간 요청 위조에 취약하며, REST의 상태 비저장 요건을 충족하지 못한다.
해결책:SSL/TLS 세션 식별자 활용
HTTPS 보안을 실행하면 일부 시스템은 애플리케이션이 SSL/TLS 세션 식별자를 얻을 수 있도록 허용한다.SSL/TLS 세션 식별자의 사용은 매우 안전하지만, 많은 웹 개발 언어는 이를 위해 강력한 내장 기능을 제공하지 않는다.null
각 요청에 대한 SID 재생성
세션 고정화에 대한 대응책은 각 요청에 대해 새 세션 식별자(SID)를 생성하는 것이다.이렇게 하면 공격자가 사용자를 속여 알려진 SID를 받아들이도록 할 수 있지만, 공격자가 SID를 재사용을 시도할 때 SID는 무효가 된다.그러한 시스템의 구현은 다음과 같이 간단하다.
- 이전 세션 식별자 가져오기
OLD_SID
HTTP 요청에서. - 만약
OLD_SID
null이거나, 비어 있거나, SID=가 있는 세션 없음OLD_SID
존재하는 경우, 새 세션을 만드십시오. - 새 세션 식별자 생성
NEW_SID
안전한 무작위 번호 생성기와 함께. - 세션을 SID=로 식별
NEW_SID
(그리고 더 이상 SID에 의한 것이 아니다=OLD_SID
) - 새 SID를 클라이언트로 전송하십시오.
예:
만약 말로리가 앨리스를 속여 방문하게 한다면http://victim.example.com/?SID=I_KNOW_THE_SID
, 이 HTTP 요청이 다음으로 전송됨victim.example.com
:
얻다 /?SID=I_KOWN_THE_SID HTTP/1.1 호스트: victim.example.com
victim.example.com
받아들이다SID=I_KNOW_THE_SID
보통은 안 좋을 거야하지만victim.example.com
세션 재생을 수행하므로 안전하다.nullvictim.example.com
다음 응답을 얻으십시오.
HTTP/1.1 200 네 알겠습니다 세트쿠키: SID=3134998145AB331F
앨리스는 이제 사용할 것이다.SID=3134998145AB331F
맬로리에게는 알려지지 않은, 그리고SID=I_KNOW_THE_SID
무효다따라서 말로리는 세션 고정 시도에 성공하지 못한다.null
불행히도 세션 재생이 항상 가능한 것은 아니다.문제는 ActiveX나 Java 애플릿과 같은 타사 소프트웨어를 사용할 때, 그리고 브라우저 플러그인이 서버와 통신할 때 발생하는 것으로 알려져 있다.타사 소프트웨어는 로그아웃을 유발하거나 세션을 두 개의 개별 세션으로 분할할 수 있다.null
세션의 구현에 GET 또는 POST 변수를 통한 SID 전송이 포함된 경우, 사용자가 이전 요청에서 유효하지 않은 오래된 세션 식별자를 사용할 수 있기 때문에 대부분의 브라우저에서 "뒤로" 버튼을 사용할 수 없게 될 수도 있다.null
서버 생성 SID만 허용
보안을 향상시키는 한 가지 방법은 서버에서 생성되지 않은 세션 식별자를 허용하지 않는 것이다.그러나 위에서 언급한 바와 같이 이것이 모든 세션 고정 공격을 방지하는 것은 아니다.null
만일 (!설정하다($_SESION['SERVER_GREATED_'SID'])) { session_properties(); // 세션의 모든 데이터 삭제 } session_session_id(); // 새 세션 식별자 생성 $_SESION['SERVER_GREATED_'SID'] = 진실의;
로그아웃 함수
로그아웃 기능은 세션이 추가 요청을 허용하지 않아야 함을 사용자가 표시할 수 있기 때문에 유용하다.따라서 공격은 세션이 활성화된 동안에만 유효할 수 있다.다음 코드는 교차 사이트 요청 위조 검사를 수행하지 않으므로 공격자가 웹 응용 프로그램에서 사용자를 강제로 로그아웃시킬 수 있다는 점에 유의하십시오.null
만일 (로그아웃하다) { session_properties(); // 세션의 모든 데이터 삭제 }
이전 SID 시간 초과
이 방어는 구현이 간단하며, 방치되었을 수 있는 기계를 이용하여 허가된 사용자 계정에 접속하는 무단 사용자에 대한 보호 수단을 제공할 수 있는 장점이 있다.null
해당 SID에 의해 수행된 마지막 액세스에 대한 타임스탬프가 포함된 세션 변수를 저장하십시오.해당 SID를 다시 사용할 경우 현재 타임스탬프를 세션에 저장된 타임스탬프와 비교하십시오.차이가 미리 정의된 숫자보다 크면, 예를 들어 5분, 세션을 삭제하십시오.그렇지 않으면 세션 변수를 현재 타임스탬프로 업데이트하십시오.null
레퍼러가 의심될 경우 세션 삭제
페이지를 방문할 때, 대부분의 웹 브라우저는 Referrer 헤더, 즉 이 페이지로 가기 위해 따라온 링크가 포함된 페이지를 설정할 것이다.null
사용자가 해당 사이트 외부에서 연결될 가능성이 없는 사이트(예: 은행 웹 사이트 또는 웹 메일)에 로그인되어 있고 해당 사이트는 사용자가 오랜 시간 동안 로그인되어 있을 수 있는 사이트가 아닌 경우, 레퍼러는 해당 사이트에서 온 사이트여야 한다.다른 레퍼러는 의심스러운 것으로 간주되어야 한다.그러나 원래 요청이 HTTPS 페이지에서 온 경우 레퍼러는 제거되므로 이 보안 시스템에 의존할 수 없다.null
예를 들면http://vulnerable.example.com/
다음과 같은 보안 검사를 사용할 수 있다.
만일 (스트로스($_SERVER['HTTP_REFERER'], 'http://vulnerable.example.com/') !== 0) { session_properties(); // 세션의 모든 데이터 삭제 } session_session_id(); // 새 세션 식별자 생성
추가 정보가 전체 세션에서 일관되는지 확인
보안을 더욱 향상시키는 한 가지 방법은 사용자가 동일한 최종 사용자(클라이언트)인 것처럼 보이도록 하는 것이다.이로 인해 세션 고정 및 기타 공격을 수행하는 것이 조금 더 어려워진다.null
점점 더 많은 네트워크가 RFC 3704 및 기타 스푸핑 방지 관행을 준수하기 시작하면서 IP 주소는 "같은 소스" 식별자로서 더욱 신뢰성이 높아진다.따라서, 소스 IP 주소가 세션 전체에 걸쳐 일치하는지 확인함으로써 웹 사이트의 보안을 향상시킬 수 있다.null
이것은 다음과 같은 방법으로 수행될 수 있다.
만일 ($_SERVER['REMOTE_ADDR'] != $_SESION['PREV_REMOTEADR']) { session_properties(); // 세션의 모든 데이터 삭제 } session_session_id(); // 새 세션 식별자 생성 $_SESION['PREV_REMOTEADR'] = $_SERVER['REMOTE_ADDR'];
그러나 이 접근법을 채택하기 전에 고려해야 할 몇 가지 사항이 있다.null
- 여러 사용자가 하나의 IP 주소를 공유할 수 있다.전체 빌딩이 NAT을 사용하여 하나의 IP 주소를 공유하는 것은 드문 일이 아니다.
- 한 명의 사용자가 일치하지 않는 IP 주소를 가질 수 있다.이는 프록시(AOL 고객 등) 뒤에 있는 사용자에게 적용된다.일부 모바일/로밍 사용자뿐만 아니라 로드 밸런싱 인터넷 연결의 배후에 있는 사용자에게도 마찬가지다.IPv6 Privacy Extensions가 활성화된 사용자는 언제든지 IPv6 개인 정보 주소를 변경할 수 있다.
- 요청이 IPv4와 IPv6 사이에서 이동하기 때문에 이중 스택 클라이언트에서는 안정적으로 작동하지 않을 것이다.
- 모바일 사용자도 주소 사이를 돌아다녀 모바일 사용자에게는 안정적으로 작동하지 않을 것이다.
어떤 사이트에서는 보안이 추가된 것이 편의성의 부족을 능가하고, 다른 사이트에서는 그렇지 않다.null
사용자 에이전트
브라우저는 "사용자-에이전트" HTTP 헤더로 자신을 식별한다.이 헤더는 일반적으로 사용 중에 변경되지 않는다. 만약 그런 일이 일어난다면 매우 의심스러울 것이다.웹 응용 프로그램은 악의적인 사용자가 세션을 도용하는 것을 방지하기 위해 사용자-에이전트 탐지를 사용할 수 있다.그러나 공격자는 공격 중에 공격 대상자의 사용자 에이전트를 자신의 사이트로 쉽게 캡처한 다음 스푸핑할 수 있기 때문에 우회하는 것은 사소한 일이다.이 제안된 보안 시스템은 무명을 통한 보안에 의존하고 있다.null
만일 ($_SERVER['HTTP_USER_AGENT'] != $_SESION['PREV_USERAGENT']) { session_properties(); // 세션의 모든 데이터 삭제 } session_session_id(); // 새 세션 식별자 생성 $_SESION['PREV_USERAGENT'] = $_SERVER['HTTP_USER_AGENT'];
그러나 이 접근법을 채택하기 전에 고려해야 할 몇 가지 사항이 있다.null
- 여러 사용자가 인터넷 카페에 동일한 브라우저 User Agent를 가지고 있을 수 있다.
- 여러 사용자가 동일한 기본 브라우저(예: Windows XP SP3의 Internet Explorer 6 또는 휴대 전화의 미니 브라우저)를 사용할 수 있다.
그러나 사용자 에이전트는 몇 가지 경우 법적으로 변경될 수 있다.다음 예제는 동일한 사용자들이다.null
- 마지막 요청 이후 화면이 회전한 스마트폰
Mozilla/5.0 (Linux; U; Android 2.2; en-us; DROID2 Build/VZW) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 854X480 motorola DROID2
Mozilla/5.0 (Linux; U; Android 2.2; en-us; DROID2 Build/VZW) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 480X854 motorola DROID2
- Internet Explorer 호환성 모드:
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
- 여러 서버에 분산된 프록시를 통해 웹 사이트에 액세스하는 사용자(모든 것이 최신 버전의 프록시 소프트웨어로 업그레이드되지 않음)
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (FlipboardProxy/0.0.5; +http://flipboard.com/browserproxy)
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (FlipboardProxy/1.1; +http://flipboard.com/browserproxy)
계층 방어; 심층 방호
![]() | 이 절에는 아마도 독창적인 연구가 포함되어 있을 것이다.(2019년 7월) (이 과 시기 |
심층 방어는 여러 가지 대응책을 병행하는 것이다.아이디어는 간단하다: 한 가지 장애물을 극복하는 것이 사소한 것이라면, 몇 가지 장애물을 극복하는 것은 매우 어려울 수 있다.null
심층 방어 전략에는 다음이 포함될 수 있다.
- HTTPS 사용(다른 문제로부터 보호)
- 올바른 구성(외부 SID 수락 안 함, 시간 초과 설정 등)
- session_regeneration, 지원 로그아웃 등 수행
HTTP 레퍼러는 SSL/TLS(HTTPS)로 전달되지 않는다.null
다음의 PHP 대본은 그러한 대응책을 심층적인 방어로 결합하여 보여준다.
만일 (설정하다($_GET['LOGOUT']) $_SERVER['REMOTE_ADDR'] !== $_SESION['PREV_REMOTEADR'] $_SERVER['HTTP_USER_AGENT'] !== $_SESION['PREV_USERAGENT']) { session_properties(); } session_session_id(); // 새 세션 식별자 생성 $_SESION['PREV_USERAGENT'] = $_SERVER['HTTP_USER_AGENT']; $_SESION['PREV_REMOTEADR'] = $_SERVER['REMOTE_ADDR'];
이 코드는 이전 요청의 REMOTE_ADDR 및 User-에이전트에 대해 현재 REMOTE_ADDR(사용자의 IP 주소) 및 User-에이전트를 점검한다는 점에 유의하십시오.이것은 위에서 논의한 바와 같이 일부 사이트에서는 불편할 수 있다.null
참고 항목
참조
외부 링크
- 보안 코너:세션 고정
- 웹 기반 응용 프로그램의 세션 고정 취약성(PDF)
- 세션 고정 비디오 예
- Web Application Security Console Threat Classification(웹 애플리케이션 보안 컨소시엄 위협 분류)