0 / 7
저장형 XSS
공격자가 게시판에 스크립트를 적어 두고 나중에 그 글을 여는 피해자의 브라우저에서 실행시키려는 상황이다. 이렇게 웹페이지에 스크립트를 삽입해 다른 사람의 브라우저에서 실행시키는 공격이 XSS다. 세 유형은 그 스크립트를 삽입하는 쪽이 서로 다르다. 저장형은 서버가 저장해 둔 글에서 꺼내 삽입한다.
예: 공격자가 게시판에 스크립트가 든 글을 올리고, 나중에 피해자가 그 글을 연다.
스크립트를 삽입하는 쪽: 서버 (저장된 글에서)
1 / 7
공격자: 스크립트가 든 글 올리기
공격자가 게시판에 글을 올리면서 내용 자리에 쿠키를 훔치는 스크립트를 적는다. 서버는 그것을 코드가 아닌 글 내용으로만 받아들인다.
2 / 7
서버: 글 저장
서버는 내용을 검사하지 않고 글을 그대로 저장한다. 스크립트가 서버에 남았지만 아직 피해를 본 사람은 없다.
3 / 7
피해자: 게시글 열기
피해자가 평소처럼 게시글을 열어 달라고 서버에 요청한다. 피해자는 잘못한 것이 없다.
4 / 7
서버: 저장된 글을 페이지에 삽입
게시글 페이지는 요청이 올 때마다 서버가 새로 만든다. 서버는 피해자에게 보낼 페이지의 기본 틀(HTML) 안에 저장된 글을 그대로 삽입한다. 그 글에 공격자의 스크립트가 들어 있어서 만들어진 페이지에도 스크립트가 들어간다. 스크립트를 삽입하는 쪽은 서버다.
5 / 7
서버 → 피해자: 페이지 보내기
서버가 완성한 페이지를 피해자에게 보낸다. 페이지 안에 스크립트가 들어 있다.
6 / 7
피해자의 브라우저: 스크립트 실행
피해자의 브라우저는 페이지에서 스크립트를 만나면 실행한다. 누가 넣은 스크립트인지는 알 수 없다. 사이트가 보낸 페이지 안의 코드라서 사이트와 같은 권한으로 실행된다. 그래서 스크립트가 읽을 수 있는 쿠키도 읽는다.
7 / 7
피해자 → 공격자: 쿠키 보내기
스크립트가 피해자의 쿠키를 공격자에게 보낸다. 공격자는 그 쿠키로 피해자인 척 로그인한다. 그 글을 여는 사람마다 같은 일이 벌어진다.
1 / 7
공격자: 악성 링크 만들기
공격자가 검색 주소의 검색어 자리에 스크립트를 적어 링크를 만든다. 서버에 저장하지 않고 링크 안에 담아 둔다.
2 / 7
공격자 → 피해자: 링크 보내기
공격자가 링크를 메일이나 메신저로 피해자에게 보낸다. 주소를 줄이거나 글자를 다른 표기로 바꾸면 스크립트가 눈에 잘 띄지 않는다.
3 / 7
피해자: 링크 누르기
피해자가 링크를 누르면 브라우저가 서버에 검색을 요청한다. 요청의 검색어 자리에 스크립트가 들어 있다.
4 / 7
서버: 검색어를 페이지에 삽입
검색 결과 페이지도 요청이 올 때마다 서버가 새로 만든다. 서버는 피해자에게 보낼 페이지 틀 안에 요청으로 받은 검색어를 그대로 삽입한다. 그 검색어에 공격자의 스크립트가 들어 있어서 만들어진 페이지에도 스크립트가 들어간다. 요청이 응답으로 그대로 되돌아와서 반사형이라고 부른다. 스크립트를 삽입하는 쪽은 서버다.
5 / 7
서버 → 피해자: 페이지 보내기
서버가 결과 페이지를 피해자에게 보낸다. 페이지 안에 스크립트가 들어 있다. 서버는 이 검색어를 따로 저장해 두지 않는다.
6 / 7
피해자의 브라우저: 스크립트 실행
피해자의 브라우저가 결과 페이지의 스크립트를 실행한다. 사이트가 보낸 페이지라서 피해자의 쿠키도 읽을 수 있다.
7 / 7
피해자 → 공격자: 쿠키 보내기
스크립트가 피해자의 쿠키를 공격자에게 보낸다. 저장형과 달리 링크를 누른 사람에게만 벌어지는 일이다.
1 / 7
공격자: 악성 링크 만들기
공격자가 사이트 주소 끝의 # 뒤에 스크립트를 적어 링크를 만든다.
2 / 7
공격자 → 피해자: 링크 보내기
공격자가 링크를 메일이나 메신저로 피해자에게 보낸다.
3 / 7
피해자: 링크 누르기
피해자가 링크를 누르면 브라우저가 서버에 페이지를 요청한다. 주소에서 # 뒤쪽은 브라우저가 서버로 보내지 않는다. 그래서 서버는 스크립트가 있다는 것조차 알지 못한다.
4 / 7
서버 → 피해자: 평소 페이지 보내기
서버는 늘 보내던 페이지를 그대로 보낸다. 스크립트는 없다. 스크립트가 서버로 오지 않는 # 뒤에 있어서 서버가 입력을 아무리 꼼꼼히 검사해도 이 공격은 막지 못한다.
5 / 7
피해자의 브라우저: 주소 글자를 페이지에 삽입
서버가 보낸 페이지는 이미 피해자의 브라우저에 와서 열려 있다. 그 안에 원래 들어 있던 자바스크립트가 주소의 # 뒤 글자를 읽어 페이지에 삽입한다. 그 글자에 공격자의 스크립트가 들어 있어서 열려 있는 페이지에도 스크립트가 들어간다. 스크립트를 삽입하는 쪽은 서버가 아니라 브라우저다. 반사형과 갈리는 점이 바로 여기다.
6 / 7
피해자의 브라우저: 스크립트 실행
브라우저가 삽입된 스크립트를 실행한다. 스크립트는 서버를 한 번도 거치지 않고 주소에서 곧바로 브라우저의 페이지로 들어왔다.
7 / 7
피해자 → 공격자: 쿠키 보내기
스크립트가 피해자의 쿠키를 공격자에게 보낸다. 서버의 요청 기록에는 주소의 # 뒤가 남지 않는다.
1 / 6
공격자: 같은 글 올리기
공격자가 저장형 때와 똑같은 글을 올린다. 내용 자리에 쿠키를 훔치는 스크립트가 들어 있다.
2 / 6
서버: 글 저장
서버는 글을 그대로 저장한다. 이 그림에서는 글이 페이지에 글자로만 나가므로 스크립트가 저장돼 있어도 피해가 없다. 막는 핵심은 저장이 아니라 페이지에 넣을 때 바꾸는 일이다.
3 / 6
피해자: 게시글 열기
피해자가 평소처럼 게시글을 열어 달라고 서버에 요청한다.
4 / 6
서버: 글자를 바꿔서 페이지에 삽입
서버가 저장된 글을 피해자에게 보낼 페이지 틀 안에 삽입하기 전에 <는 <로, >는 >로 바꾼다. 그래서 글 속 <script>가 <script>가 된다. 삽입하는 쪽은 여전히 서버지만, 이제 코드가 아니라 글자를 넣는다.
5 / 6
서버 → 피해자: 페이지 보내기
서버가 페이지를 피해자에게 보낸다. 페이지에는 <script>가 아니라 <script>라는 글자가 들어 있다.
6 / 6
피해자의 브라우저: 글자로 표시
피해자의 브라우저는 <를 코드의 시작이 아니라 < 글자로 화면에 보여 준다. 스크립트는 실행되지 않고 게시글에 코드가 글자 그대로 찍혀 보일 뿐이다. 쿠키는 공격자에게 넘어가지 않는다.