검수요청.png검수요청.png

사이트 간 스크립팅

위키원
이동: 둘러보기, 검색

사이트 간 스크립팅(cross-site scripting, XSS)은 웹 애플리케이션에서 많이 나타나는 취약점의 하나로 웹사이트 관리자가 아닌 이가 웹 페이지에 악성 스크립트를 삽입할 수 있는 취약점이다. 크로스-사이트 스크립팅이라고도 한다. 주로 여러 사용자가 보게 되는 전자 게시판에 악성 스크립트가 담긴 글을 올리는 형태로 이루어진다.

개요

사이트 간 스크립팅은 웹 애플리케이션이 사용자로부터 입력 받은 값을 제대로 검사하지 않고 사용할 경우 나타난다. 이 취약점으로 해커가 사용자의 쿠키, 세션 등의 정보를 탈취하거나, 자동으로 비정상적인 기능을 수행하게 할 수 있다. 주로 다른 웹사이트와 정보를 교환하는 식으로 작동하므로 사이트 간 스크립팅이라고 한다.[1]

특징

공격 유형

사이트 간 스크립팅의 공격 유형은 표준화로 정해져 있지 않지만, 전문가들은 사이트 간 스크립팅의 유형을 구분한다. 비 지속적인 공격(Non-persistent XSS)과 지속적인 공격(Persistent XSS), 그리고 소스 코드 추가로 발생하는 문서 객체 모델(Document Object Model, DOM) 기반 사이트 간 스크립팅 등의 유형으로 구분한다.

  • 비 지속적 기법
비 지속적 사이트 간 스크립팅(Non-persistent XSS)은 반사 사이트 간 스크립팅(Reflected XSS)이라고도 불리며, 가장 일반적인 유형이다. 웹 클라이언트가 제공하는 HTTP 쿼리 매개 변수에서 적절하지 않고, 구문 분석 및 해당 사용자에 대한 결과의 페이지를 표시하는 공격 기법이다. 검증되지 않은 사용자가 URL 피라미터나 HTTP 요청 헤더 정보를 수정하여 공격할 수 있다. 잠재적인 취약점이 존재하는 대상은 검색 엔진으로, 검색 엔진의 검색창에서 하나의 문자열을 검색하는 경우, 검색 문자열은 일반적으로 결과 페이지에 그대로 노 다시 표시된다. 삽입된 문자열을 다시 표시하면서 문자열이 가지고 있는 스크립트가 동작한다면 취약점이 존재하는 것이다.[1]
  • 지속적 기법
지속적 사이트 간 스크립팅(Persistent XSS)은 더 치명적인 기법이다. 공격자가 제공한 데이터가 서버에 저장된 다음 지속해서 서비스를 제공하는 정상 페이지에서 다른 사용자에게 노출된다. 해당 취약점이 대표적으로 발생하는 위치는 사용자가 읽을 수 있고, HTML 형식의 메시지를 게시 할 수 있는 온라인 게시판이 해당한다. 공격자의 악의적인 스크립트가 피해자를 일일이 제 3자 웹 사이트로 유인할 필요 없이, 자동으로 렌더링 되기 때문에 지속적인 사이트 간 스크립팅 취약점은 다른 유형보다 더 위험하다.[1]
  • 문서 객체 모델 기반
문서 객체 모델 기반 사이트 간 스크립팅(이하 DOM XSS)은 W3C 표준으로 HTML 및 XML 문서에 접근 방법을 표준으로 정의하는 문서 객체 모델로, 공격 과정은 빅팀(Victim)의 브라우저가 HTML 페이지를 구문 분석할 때마다 공격 스크립트가 DOM 생성의 일부로 실행되면서 공격한다. 페이지 자체에는 변화가 없으나 페이지에 포함된 브라우저 측 DOM 환경에서 악성코드가 실행된다. 다른 기법들과는 달리 서버와 관계없이 발생하는 것도 특징이다.[2]

목적

  • 쿠키 정보/세션 ID 획득
쿠키란 웹 서버가 HTTP 헤더 중 셋-쿠키(set-Cookie) 필드로 브라우저에 보내는 4KB 이하의 작은 텍스트 파일이며, 사용자가 웹 사이트를 이용하는 동안 사용자 브라우저에 저장된다. 사용자가 웹 사이트의 페이지를 클릭할 때마다 브라우저는 웹 서버에게 사용자의 상태를 다시 알려준다. 사용자 상태를 기록하기 위해 쿠키값에 로그인, 버튼 클릭 등에 대한 정보를 저장한다. 세션 쿠키는 사용자가 웹 사이트를 읽거나 방문하는 동안에만 임시로 메모리에 존재하는 쿠키이고 쿠키 생성 시 쿠키 만료 시기 또는 유효성 기간이 설정되어 있지 않은 경우에 세션 쿠키가 만들어진다. 브라우저에서는 사용자가 브라우저를 종료하면 세션 쿠키를 삭제한다. 웹 애플리케이션이 세션 ID를 쿠키에 포함하는 경우 사이트 간 스크립팅 공격을 통해, 클라이언트의 합법적인 세션 ID를 획득하여 불법적으로 정상 사용자로 가장할 수 있다.
  • 시스템 관리자 권한 획득
사이트 간 스크립팅 취약점을 이용하여 사용자 브라우저 취약점을 공격해 컴퓨터를 완전히 통제할 수도 있다. 공격자는 사이트 간 스크립팅 취약점이 있는 웹 서버에 다양한 악성 데이터를 포함해 놓은 후, 사용자의 브라우저가 악성 데이터를 실행하는 경우 자신의 브라우저에 있는 제로데이 취약점 또는 패치되지 않은 취약점을 공격하는 공격 코드가 실행되면서 사용자 시스템을 완전히 통제할 수 있다. 회사 등 조직의 개인 컴퓨터가 해킹되는 경우 조직의 내부 시스템으로 이동하여 내부의 중요 정보를 탈취하는 공격으로 이어질 수 있다.
  • 악성코드 다운로드
사이트 간 스크립팅 공격은 악성 스크립트 자체만으로는 악성 프로그램을 다운로드할 수 없지만, 사용자가 악성 스크립트가 있는 URL을 클릭하도록 유도하여 악성 프로그램을 다운로드받는 사이트로 리다이렉트(redirect) 하거나, 트로이목마 프로그램을 다운로드하여 설치할 수 있다.[3]

대안

사이트 간 스크립팅 취약점은 쉽게 악용될 수 있으며, 공격 효과도 커 공격자들이 자주 이용하는 기술이다. 많은 조직에서 사이트 간 스크립팅 공격을 대응하기 위해 웹 방화벽(WAF)을 도입하여 방어를 하고 있다. 그러나 대부분의 웹 방화벽은 시그너쳐 기반의 사이트 간 스크립팅 공격만을 탐지하고 있어 특정 문자열을 탐지하는 기술을 쉽게 우회가 가능하여 방어가 효과적이지 못하다. 또한 웹 애플리케이션 개발자는 <스크립트> 태크 등 브라우저에서 실행되는 위험한 문자를 중성화하여 사이트 간 스크립팅 취약점을 예방하고 있다. 하지만 웹 개발자들이 일일이 수동적으로 위험한 문자를 필터링 및 인코딩하는 것은 현실적으로 불가능하고 취약점이 잔존하게 된다. 이러한 방식으로 인해 중소 및 대형 웹사이트 등에서 사이트 간 스크립팅 취약점이 지속적해서 발견되고 있다.[3]

입・출력 값 검증 및 무효화

사이트 간 스크립팅 취약점을 근본적으로 제거하기 위해서는 스크립트 등 해킹에 사용될 수 있는 코딩에 사용되는 입력 및 출력값에 대해서 검증하고 무효화시켜야 한다. 입력값에 대한 유효성 검사는 데이터가 입력되기 전에 가능하면, 입력 데이터에 대한 길이, 문자, 형식 및 사업적 규칙 유효성을 검사해야 한다. 출력값을 무효화하기 위햐서는 사이트 간 스크립팅 공격은 기본적으로 <스크립트> 태크를 사용하기 때문에 사이트 간 스크립팅 공격을 차단하기 위해 태그 문자 (<,>) 등 위험한 문자 입력 시 문자 참조(HTML entity)로 필터링하고, 서버에서 브라우저로 전송 시 문자를 인코딩한다. HTML 문자 참조랑 아스키(ASCII) 문자를 동일한 의미의 HTML 문자로 변경하는 과정이다.
[그림1] 위험 문자 인코딩
ASCII 문자 참조 문자 ASCII 문자 참조 문자
& &amp ; " &quot ;
< &lt ; ' &#x27 ;
> &gt ; / &#x2F ;
( &#40 ; ) &#41 ;

[그림 1]은 HTML 문서에서 악성 스크립트에 포함되어 브라우저에서 실행될 수 있는 문자와 대체 문자를 정리한 것으로 악성 스크립트는 많은 HTML 태그 안에 포함할 수 있음으로 반드시 [그림 1]에 있는 위험 문자의 경우 출력값을 이스케이핑 해야 한다.

[그림2] 사이트 간 스크립팅 예방 기법
데이터 형식 콘텍스트 코딩 예 방어책
String(문자열) HTML Body 악성 데이터
  • HTML Entity
String(문자열) 안전한 HTML Attributes <input type="text" name="fname" value="악성 데이터">
  • HTML Entity 인코딩
  • 악성 데이터를 화이트리스트 방식 또는 안전한 속성에만 위치
  • background, id 및 name과 같은 안전하지 않은 속성을 철저히검증
String(문자열) GET 피라미터 <a href="/site/search?value=악성 데이터">clickme</a>
  • URL 인코딩
String(문자열) SRC 또는HREF 속성에 악성 URL

<a href="악성 URL">clickme</a> <iframesrc="악성 URL" />

  • 입력 값 정규화
  • URL 검증
  • URL 안정성 확인
  • 화이트 리스트된 http 및 https URL만 허용
  • 속성 인코더 사용
String(문자열) CSS 값 < div style = " width : 악성 데이터;">Selection</div>
  • 엄격하게 구조적 검증
  • CSS 16진수 인코딩
  • CSS 기능 설계 강화
String(문자열) 자바스크립트 변수

<script>var currentValue='악성 데이터';</script> <script>함수('악성 데이터');</script>

  • 자바스크립트 변수를 문자화
  • 자바스크립트 헥스 인코딩
  • 자바스크립트 16진수 인코딩
  • 자바스크립트 유니코드 인코딩
  • 백슬래쉬 사용금지
HTML HTML Body
악성 HTML
HTML 검증
String(문자열) DOM XSS

<script>document.write("악성 입력 값: " + document.location.hash);<script/>

  • DOM 기반 XSS 예방

[그림 2]는 악성 스크립트 등 악성 데이터가 포함되어 브라우저를 공격할 수 있는 다양한 방법의 HTML 태그를 정리해 놓은 것이다. 여기에 있는 '악성 데이터', '악성 URL' 및 '악성 HTML', '악성 자바스크립트' 등이 포함될 수 있는 곳이다. 즉 웹 애플리케이션 개발자들은 웹 문서의 코딩 시 [그림 2]에 있는 태그에 포함될 악성 데이터에 대해서 반드시 입, 출력 값을 검증해야 한다. 하지만 애플리케이션 개발자가 많은 태그의 입력 문자를 검증하기 위해 코딩 시 일일이 작업하는 것은 많은 노력과 자원이 소모된다. 또한 인코딩 방식을 통해 방어기술을 무력화할 수 있음으로 애플리케이션 개발자가 직접 모두 처리하는 것은 불가능하다. 그래서 입, 출력값을 자동으로 검증해주는 라이브러리를 사용하면 좀 더 효과적으로 대응할 수 있다.[3]

보안 라이브러리

  • 안티 사이트 간 스크립팅(AntiXSS)
안티 사이트 간 스크립팅 라이브러리는 마이크로소프트사에서 개발한 공개용 사이트 간 스크립팅 취약점 예방 라이브러리이다. 이 라이브러리는 입력값을 검증하여 서버로 악성 스크립트가 입력되지 못하는 기능과 위험한 문자를 인코딩하는 함수를 제공한다. [그림 3]은 안티 사이트 간 스크립팅에서 제공하는 위험한 데이터 출력 시 인코딩해주는 메소드이다.
[그림3] AntiXSS의 XSS 예방 인코딩 메소드
메소드 사용처 코딩 예
HtmlEncode 신뢰할 수 없는 데이터가 HTML 바디 부분에 출력되는 경우 <span>[악성 데이터]</span>

<p>Hello [악성 데이터]</p>

HtmlAttrEncode HTML 속성에 신뢰할 수 없는 데이터를 추가해야 하는 경우 <input type="text" name="fname" value="[악성데이터]">

<p id="[악성 데이터]"></p>

UrlQueryEncode URL 내에 쿼리 문자열 값에 신뢰할 수 없는 데이터를 추가해야 하는 경우 <a href="/site/search?value=[악성 데이터]"> clickme</a>

JavaScriptEncode

JavaScriptEncode 신뢰할 수 없는 데이터를 자바스크립트 변수에 지정할 경우 <script>var currentValue='[악성 데이터]';</script>

<script>someFunction('[악성 데이터]');</script>

XmlEncode XML 데이터 부분에 신뢰할 수 없는 데이터를 출력하는 경우 <name>[악성 데이터]</name>
XmlAttrEncode XML 속성 값에 신뢰할 수 없는 데이터를 추가해야 하는 경우 <name firstName="[악성 데이터]"></name>
GetSafeHtml HTML 바디에 신뢰할 수 없는 HTML을 출력하는 경우 <div>[악성 HTML]</div>
  • OWASP ESAPI 라이브러리
OWASP는 포괄적인 애플리케이션 보안을 위해 웹 응용 취약점에 대응할 수 있는 오픈소스 ESAPI 라이브러리를 개발하여 제공하고 있다. ESAPI에는 총 14개의 API가 있으며, 이 중 사이트 간 스크립팅 취약점을 예방하기 위해 API는 유효성 검사(validator)와 엔코더(encoder)가 있다. 유효성 검사는 입력값을 필터링하는 기능을 하고 엔코더는 출력값을 인코딩 및 디코딩하는 기능을 가지고 있다. 이 라이브러리는 자바, PHP, NET, ASP, 자바스크립트 및 파이썬 등 다양한 애플리케이션 개발언어를 지원하고 있다.

브라우저 확장 프로그램

애플리케이션 개발 시 이용하는 라이브러리 이외에도 사용자가 사이트 간 스크립팅 공격을 예방할 수 있는 프로그램도 있다. 노스크립트(NoScript)는 파이어폭스 등 모질라 기반의 브라우저에서 실행되는 오픈소스 확장 프로그램으로, 화이트 리스트 기반으로 신뢰 된 사이트의 자바스크립트, 플래쉬, 실버라이트 및 액티브 엑스 등 동적 스크립트만 브라우저에서 실행하도록 하여 사이트 간 스크립팅 공격을 예방할 수 있다.[3]

각주

  1. 1.0 1.1 1.2 사이트 간 스크립팅〉, 《위키백과》
  2. Security/3. WEB Sec, 〈XSS(Cross Site Scripting)〉, 《CIO Korea》, 2019-03-29
  3. 3.0 3.1 3.2 3.3 성윤기, 〈크로스 사이트 스크립팅(XSS) 공격 종류 및 대응 방법 〉, 《한국인터넷진흥원》, 2013-12-16

참고자료

같이 보기


  검수요청.png검수요청.png 이 사이트 간 스크립팅 문서는 보안에 관한 글로서 검토가 필요합니다. 위키 문서는 누구든지 자유롭게 편집할 수 있습니다. [편집]을 눌러 문서 내용을 검토·수정해 주세요.