난이도 : 초급 Paul Lee, I/T Architect, IBM Global Services 2002 년 9 월 01 일
오늘날 대부분의 웹 사이트는 동적 컨텐트를 웹 페이지에 추가하여 사용자에게 더 많은 즐거움을 선사한다. 동적 컨텐트는 몇몇 서버 프로세스에서 만들어진 컨텐트로서, 설정과 필요에 따라 다르게 작동하고 디스플레이 된다. 동적 웹 사이트는 정적 웹 사이트에는 없는 위험성도 지니고 있다. 이를 "크로스 사이트 스크립팅(cross-site scripting) "이라고 한다. 일명 "XSS"라고도 알려져 있다. "웹 페이지는 텍스트와 HTML 마크업으로 구성된다. 이들은 서버에 의해 만들어지고 클라이언트 브라우저에 의해 인터프리팅 된다. 정적 페이지만을 만들어 내는 웹 사이트는 브라우저 사용자가 이러한 페이지들을 인터프리팅하는 방식을 완전히 제어할 수 있다. 동적 페이지를 만들어 내는 웹 사이트는 클라이언트가 아웃풋을 인터프리팅 하는 방식을 완전히 제어하지는 못한다. 신뢰할 수 없는 컨텐트가 동적 웹 페이지에 들어갈 수 있다는 것이 문제의 본질이다. 웹 사이트나 클라이언트도 이러한 현상을 인식하여 방어할 수 있는 충분한 정보가 없다." 인터넷 보안 취약성을 연구하는 CERT Coordination Center의 설명이다. 크로스 사이트 스크립팅은 공격자들에게는 이미 유명해졌다. 매월 크로스 사이트 스크립팅 공격이 상용 사이트에서 발생하고 그러한 위험성을 설명하는 경고문이 발표된다. 주의하지 않는다면 여러분의 웹 사이트나 회사도 이러한 공격의 희생양이 될 것이다. 이 글에서 이러한 위협에 대한 경각심을 일깨우고 웹 애플리케이션에 보안을 구현하여 공격을 피하는 방법을 설명하고자 한다. 크로스 사이트 스크립팅으로 인해 다음과 같은 위험에 빠지게 된다.
웹 사이트상의 애플리케이션이 크로스 사이트 스크립팅에 취약하다고 알려지면 공격자는 공격을 구상하게 된다. 공격자가 가장 빈번하게 사용하는 기술은 공격 목표의 시스템에 공격 목표의 권한을 사용하여 실행할 수 있도록 JavaScript, VBScript, ActiveX, HTML, Flash를 투입하는 것이다. 공격이 활성화 되면 계정 하이재킹, 사용자 설정 변경, 쿠키 훔치기 및 오염, 오류 광고 등이 가능하다.
다음 시나리오 다이어그램은 비교적 빈번하게 발생하는 공격 유형이다. 다양한 취약성 유형들까지 다 설명할 수는 없다. 자세한 내용은 아래 참고자료 섹션을 참조하기 바란다. 이 시나리오에서 공격자는 특별하게 고안한 이메일 메시지를 공격 목표로 보낸다. 여기에는 아래와 같은 악의적인 링크 스크립팅이 포함되어 있다. <A HREF=http://legitimateSite.com/registration.cgi?clientprofile=<SCRIPT>malicious code</SCRIPT>>Click here</A>
아무것도 모르는 사용자가 이 링크를 클릭하면 URL은 악의적인 코드를 담고 있는 그림 1. 이메일을 통한 공격 웹 사이트의 일부가 쿠키를 사용한다면 사용자에게서 쿠키를 훔칠 수도 있다. 이 시나리오에서, 공격자는 악의적인 스크립트를 가진 페이지를 취약한 사이트의 일부에 끼워넣는다. 페이지가 디스플레이 되면 악의적인 스크립트가 실행되고 사용자 쿠키를 모으고 요청을 공격자의 웹 사이트로 보낸다. 이 방법을 사용하여 공격자는 패스워드, 신용카드 번호, 사용자 인풋 정보 등의 민감한 데이터를 취할 수 있다.( 그림 2) 그림 2. 쿠키 훔치기와 계정 하이재킹 이 시나리오에서 사용자는 메일 메시지의 악의적인 링크를 따라가게 되면 공격자가 작성한 스크립트를 실행한다. 악의적인 스크립트는 합법적인 서버에서 온 것 처럼 보이는 상황 속에서 실행되기 때문에 공격자는 문서에 접근할 수 있으며 페이지에 포함된 데이터를 사이트로 보낼 수 있다. 그림 3. 비권한 요청 보내기
앞서 언급했던 것 처럼, 공격자가 합법적인 웹 서버가 공격자가 선택한 악의적인 스크립트를 포함하고 있는 대상 사용자의 웹 브라우저로 페이지를 보냄으로서 크로스 사이트 스크립팅이 실현된다. 공격자는 합법적인 웹 서버에서 온 합법적인 스크립트 권한을 갖고 악의적인 스크립트를 실행한다. 지금까지 공격의 기초에 대해 알아보았다. 이제는 방어할 차례이다. 웹 사이트 개발자는 동적으로 생성된 페이지들에 원치 않던 태그가 포함되지 않도록 함으로서 공격을 피할 수 있다. 웹 사용자의 관점에서 볼 때 공격 위험성을 줄이는 두 가지 옵션이 있다. 첫 번째는 웹 브라우저 뿐만 아니라 HTML 이메일 클라이언트에서 스크립팅 언어가 실행되지 못하게 하는 것이다. 이는 강력한 보호막이 되지만 기능까지 수행하지 못하게 한다는 점이 부작용이다. 두 번째는 메인 웹 사이트에서 온 링크만 따라가는 것이다. 이는 사용자 노출을 최대한 줄이면서 기능은 유지된다. 하지만, 웹 사용자가 선택할 수 있는 솔루션 중 어떤 것도 완벽한 것은 없다. 결국 페이지를 수정하여 문제를 줄이는 웹 페이지 개발자의 손에 달려있다. 인풋을 적절히 필터링 및 확인하고 사용자에게 갈 아웃풋을 암호화 및 필터링 해야 한다. 이러한 접근 방식의 기초는 사용자 인풋을 절대 신뢰하지 말고 HTML 스팩에서 정의된 메타문자("특수" 문자)를 언제나 필터링 하는 것이다. 링크 매개변수를 포함하여 각 인풋 필드는 스크립트 태그에 대해 밸리데이션 될 것이다. 악의성이 발견되면 인풋은 거절되고 악의적인 HTML이 사용자에게 제공되는 것을 막을 수 있다. 게다가 많은 웹 브라우저가 HTML에서 일반적인 에러를 수정하려 들기 때문에 복잡해 진다. 결과적으로 그 스팩에 의해 문자를 특수 문자로 취급한다. 전혀 그렇지 않은데 말이다. 따라서 특수한 상황이 있다는 것도 인정해야 한다 웹 개발자들은 애플리케이션을 검사하고 어떤 문자들이 자신의 웹 애플리케이션에 영향을 미치는지를 결정해야 한다. 인풋쪽에서 필터링 하는 것은 덜 효과적이다. 동적 컨텐트는 HTTP외 다른 방식을 통해 웹 사이트 데이터베이스로 들어갈 수 있기 때문이다. 이 경우, 웹 서버는 데이터 인풋 프로세스의 일부가 되는 데이터를 결코 볼 수 없고 데이터 엘리먼트는 여전히 오염된 상태로 남아있다. 가끔은 데이터 아웃풋 프로세스의 일부로 필터링을 수행하는 것이 좋다. 동적 페이지의 일부로 렌더링 되기 바로 직전에 말이다. 정확히만 수행된다면 이러한 접근 방식을 통해 모든 동적 컨텐트가 필터링 될 수 있다. 웹 서버가 모아진 페이지들이 적절히 암호화 되어 의도하지 않던 스크립트의 실행을 방지할 때 크로스 사이트 스크립팅 공격을 피할 수 있다. ISO-8859-1 스팩의 각 문자는 숫자 엔트리 값을 사용하여 암호화 될 수 있다. 서버측 암호화란 스크립팅 태그들이 선택된 문자 세트의 코드로 대체되는 곳에서 모든 동적 컨텐트가 암호화 기능을 수행하는 프로세스이다. 여러분은 어떤 문자가 합법적으로 입력되고 통과할 수 있는지를 결정할 수 없기 때문에 암호화가 필요하다. 안타깝게도, 신뢰할 수 없는 모든 데이터를 암호화 하면 리소스 중심이 될 수 있고 몇몇 웹 서버의 퍼포먼스에 영향을 미칠 수 있다.
브라우저에서 필드 편집 체크를 하는 CGI 기반 웹 애플리케이션이나 기타 애플리케이션들은 기존 필드 편집 체크를 확장하여 크로스 사이트 스크립팅 취약성까지 아우르는 필터링 전략에 알맞다. 브라우저 측 필드 편집 체크가 서버로 가는 몇 가지 실행을 줄여주기는 하지만, 정직한 사용자에게만 해당하고 모든 인풋 필드가 체크되었다는 것을 보장하기 위해서는 코드 전체를 검사해야 한다. 서버측 밸리데이션으로 설계된 웹 애플리케이션은 두 전략 중 하나 또는 모두에 적용될 수 있다. 필터링 전략이 효과를 거두기 위해서는 웹 개발자들은 필터링용 메타문자 리스트가 최신 애플리케이션의 필요에 맞는 것인지를 확인해야 한다. 반면, 암호화 전략은 기존 애플리케이션 코드와 애플리케이션 기능에 영향을 덜 미친다. 이 같은 이유 때문에 암호화 전략이 구현 시 많이 선택된다. 암호화 구현 샘플은 다음에 설명하겠다.
웹 서버가 생성된 페이지들이 알맞게 암호화 되었다는 것을 확인할 수 있는 간단하지만 효과적인 방법은 암호화 기능을 통해 동적 컨텐트의 각 문자로 전달하는 것이다. 이때 동적 컨텐트의 스크립팅 태그는 선택된 문자 세트의 코드로 대체된다. 이 작업은 커스텀 태그 라이브러리에 가장 적합하다. 커스텀 태그 라이브러리는 한 개 이상의 자바 클래스(태그 핸들러)와 XML 태그 라이브러리 디스크립션 파일(TLD)로 구성된다. 이것은 새로운 태그 이름과 그러한 태그에 유효한 애트리뷰트를 나타낸다. 태그 핸들러와 TLD는 태그, 애트리뷰트, 바디가 JSP 페이지 내에서 요청 시 어떻게 인터프리팅 되고 처리되는지를 결정한다. 커스텀 태그 라이브러리는 복잡한 연산을 캡슐화 할 때 자바 빈 보다 유연한 아키텍처를 제공한다.
이러한 인터랙션을 통해 우리의 XSS 커스텀 태그 라이브러리는 JSP 페이지에서 발견된 동적 데이터를 암호화 하는 "사용자" 액션을 사용할 수 있다. 커스텀 태그를 구현하는 일은 단순하다.
태그 라이브러리 디스크립터는 엘리먼트가 특정 태그 라이브러리를 기술하는 XML 파일이다. Listing 1. xss.tld 파일
taglib 명령어는 태그 라이브러리 디스크립터를 구분하고 후속 태그와 라이브러리를 연결하는 태그 접두사를 정의한다.
태그 핸들러는 JSP 페이지가 실행될 때 액션들을 평가하는 것을 돕는 웹 컨테이너에 있는 객체이다. Listing 2. 동적 컨텐트의 암호화
다음 시나리오에서는 커스텀 태그 라이브러리가 어떻게 사용되는지를 설명한다. 아티클을 받는 가상의 웹 사이트에 제출된 아티클을 리뷰하는 페이지를 포함시켰다. 동적 컨텐트인 아티클 아이템은 공격자가 악의적인 스크립트를 포함하고 있는 페이지를 등록된 회원의 웹 사이트에 넣었다. 이러한 공격의 결과로 사용자 브라우저에서 실행될 때 팝업 창이 뜬다. ( 그림 4) 그림 4. 암호화 전 다음 시나리오에서는 가상의 웹 사이트에서 생성된 페이지들이 그림 5. 암호화 후
공격자들이 크로스 사이트 스크립팅을 사용하여 웹 사이트를 공격하는 방법을 설명했다. 또한 웹 사이트가 간단한 커스텀 태그 라이브러리를 사용하여 동적 컨텐트를 암호화 하는 것으로도 이러한 공격을 줄일 수 있다는 것을 설명했다.
|