XSS는 폼에 입력한 텍스트가 다른 사람의 화면에서 스크립트로 실행되는 취약점입니다. 동작 원리와 확실하게 막는 방법을 설명합니다(공격 절차 없음).
세 가지 유형
XSS는 "악성 문자열이 실행에 이르는 방식"으로 나뉩니다.
| 유형 | 심어지는 방식 |
|---|---|
| 저장형(Stored) | 게시물/프로필에 저장되어 그것을 보는 모든 사람에게 실행됨 (가장 위험) |
| 반사형(Reflected) | URL 파라미터가 페이지에 곧장 반사되어 돌아옴. 링크를 클릭하는 누구에게나 실행됨 |
| DOM 기반 | 서버 왕복 없음 — 클라이언트 측 JS가 입력을 안전하지 않게 처리 |
왜 위험한가 (동작 원리)
브라우저는 페이지 안의 어떤 <script> 든 "정당한 코드"로 실행합니다. 공격자의 문자열이 페이지에 HTML로 들어가면, 브라우저는 그것을 진짜 코드와 구별하지 못합니다.
피해는 "그 페이지가 할 수 있는 모든 것"입니다. RCE 가 서버 측에서 가장 심각한 결함이라면, XSS는 클라이언트(사용자) 측에서 가장 심각한 결함입니다.
방어: 출력 시 이스케이프
XSS는 입력이 아니라 출력에서 예방됩니다. 값을 렌더링하는 순간, HTML로 해석될 수 없도록 변환하세요.
출력 시 이스케이프 (가장 중요)
사용자 제공 값을 렌더링할 때 < > & " ' 를 HTML 엔티티로 변환하세요 — 맥락(HTML 본문, 속성, JS, URL)에 맞는 방법으로.
프레임워크의 자동 이스케이프를 끄지 않기
React/Vue/템플릿은 기본으로 자동 이스케이프합니다. 날 HTML 주입(dangerouslySetInnerHTML, v-html)만 피하면 대부분의 XSS를 예방합니다.
CSP로 심층 방어
Content-Security-Policy는 브라우저가 허용하지 않은 스크립트를 차단하게 해, 무언가 빠져나가도 피해를 제한합니다.
쿠키 보호
세션 쿠키에 HttpOnly 를 표시해 JS가 읽지 못하게 하세요. XSS가 통과하더라도 피해가 작아집니다.
본 사이트의 견해: 최선의 방어는 안전 기능을 스스로 끄지 않는 것
현대 프레임워크는 기본이 안전합니다. 대부분의 XSS는 개발자가 "날 HTML을 주입"하려고 일부러 자동 이스케이프를 끄는 순간에 나타납니다. HTML을 정말 허용해야 한다면, 직접 만든 문자열 처리가 아니라 충분히 검증된 정화기를 거치세요. "편의를 위해 안전을 끄는 것"이 가장 큰 위험입니다.
헷갈리기 쉬운 공격과의 차이
XSS는 이름이 비슷한 CSRF, 그리고 입력이 명령으로 취급된다는 점이 같은 SQL 인젝션과 자주 혼동됩니다. 차이는 무엇이 어디서 실행되느냐입니다.
| 공격 | 어디서 무슨 일이 일어나나 | 주된 방어 |
|---|---|---|
| XSS | 공격자의 스크립트가 실제 페이지의 일부로 사용자의 브라우저에서 실행됨 | 출력 시 이스케이프, CSP |
| CSRF | 사용자의 로그인 세션으로 본인이 의도하지 않은 요청이 전송됨. 스크립트 실행은 필요 없음 | CSRF 토큰, SameSite 쿠키 |
| SQL 인젝션 | 서버에서 입력이 SQL 문의 일부로 해석됨 | 플레이스홀더 |
| 클릭재킹 | 실제 페이지를 보이지 않게 겹쳐 사용자가 모르고 클릭하게 함 | CSP frame-ancestors |
XSS는 CSRF 대책도 무력화한다는 점에 주의하세요. 스크립트가 페이지 안에서 실행되면 그 페이지의 CSRF 토큰도 읽을 수 있습니다(OWASP의 CSRF 가이드도 같은 경고를 합니다).
실제 사례: 직원이 여는 화면의 XSS
2026년, 학습 관리 시스템 Canvas를 운영하는 Instructure는 침입이 XSS에서 시작되었다고 밝혔습니다. 회사에 따르면 공격자는 무료 계정으로 악성 코드가 담긴 지원 티켓을 제출했고, 지원 담당자가 그것을 열었을 때 XSS 결함이 악용되어 Canvas 내부의 높은 권한을 얻었습니다(→ Canvas(Instructure) 데이터 유출(영문)).
교훈은 XSS가 공개 페이지만의 문제가 아니라는 점입니다. 외부에서 보낸 텍스트를 자사 직원에게 보여 주는 지원, 문의, 관리 화면은 그것을 여는 계정의 권한이 크기 때문에 위험이 더 큽니다.
XSS는 지금도 가장 흔한 약점 중 하나입니다. 2025년 12월 공개된 MITRE의 "CWE Top 25"(가장 위험한 소프트웨어 약점 25개)에서 XSS(CWE-79)는 1위였습니다. 2024년 9월에는 미국 CISA와 FBI도 소프트웨어 제조사에 제품에서 XSS를 없애라고 요청하는 경보를 냈습니다.
내 사이트에서 확인하는 방법
공격 문자열을 시험해 볼 필요는 없습니다. 다음 네 가지부터 확인하세요.
날 HTML을 넣는 곳을 찾는다
코드에서 dangerouslySetInnerHTML, v-html, innerHTML, document.write를 검색하고, 사용자가 보낸 값이 거기에 닿을 수 있는지 확인합니다. 닿는다면 텍스트로 표시하도록 바꾸거나 검증된 정화기를 거치게 하세요.
세션 쿠키의 플래그를 확인한다
브라우저 개발자 도구(Application → Cookies)에서 세션 쿠키에 HttpOnly와 Secure가 붙어 있는지 확인합니다. 사이트 점검도 쿠키 플래그를 검사합니다.
관리 화면과 지원 화면도 포함한다
외부에서 온 텍스트(티켓 본문, 파일 이름, 표시 이름)를 보여 주는 내부 화면도 공개 페이지와 같은 기준으로 이스케이프되는지 확인하세요.
출처(1차 자료)
- OWASP, "Cross Site Scripting Prevention Cheat Sheet" — cheatsheetseries.owasp.org(출력 맥락별 이스케이프, 프레임워크의 안전한 기본값)
- MITRE, "2025 CWE Top 25 Most Dangerous Software Weaknesses"(2025년 12월) — cwe.mitre.org(CWE-79가 1위)
- CISA·FBI, "Secure by Design Alert: Eliminating Cross-Site Scripting Vulnerabilities"(2024년 9월 17일) — cisa.gov
- OWASP, "Cross-Site Request Forgery Prevention Cheat Sheet" — cheatsheetseries.owasp.org(XSS는 CSRF 대책을 우회할 수 있음)
- IPA, "안전한 웹사이트 만드는 법"(일본어) — ipa.go.jp
다음으로 읽기
- 용어집: CSRF란 · RCE란 · JWT란 (XSS로 자주 탈취되는 토큰)
- 심층 방어: 보안 헤더는 쌓아 두는 목록이 아니다(영문)(CSP는 XSS가 할 수 있는 일을 좁힌다)
- 기초: 보안 기초