웹 보안에서 자주 언급되는 위협 중 하나가 바로 "XSS"입니다. 이는 사용자 입력을 제대로 처리하지 못한 결과로 발생하며, 공격자가 악성 스크립트를 삽입해 사용자나 시스템에 피해를 줄 수 있는 위험한 취약점입니다. 특히 XSS는 OWASP Top 10에서 꾸준히 상위권을 차지하고 있으며, 보안을 고려한 웹 개발에서 반드시 인지하고 대응해야 할 핵심 항목으로 평가됩니다.
A. XSS의 정의
"XSS"는 "Cross-Site Scripting"의 약자입니다. 다만 CSS와 혼동을 피하기 위해 약어로는 XSS로 표기합니다. XSS는 공격자가 악성 스크립트를 웹페이지에 삽입하여, 해당 페이지를 열람한 사용자의 브라우저에서 의도하지 않은 자바스크립트가 실행되도록 만드는 공격 기법입니다. 이로 인해 쿠키 탈취, 세션 하이재킹, 피싱 등의 다양한 보안 사고가 발생할 수 있습니다.
OWASP(국제 웹 보안 프로젝트)의 Top 10 웹 취약점 목록에서 XSS는 매년 상위권에 포함되며, 그 심각성과 빈도가 입증되고 있습니다.
B. 작동 원리
XSS는 사용자의 브라우저에서 자바스크립트 같은 클라이언트 스크립트를 실행하게 만드는 방식입니다. 공격자는 보통 입력폼, 댓글, 검색어 입력창 등에 스크립트 태그(<script>)를 삽입하고, 이것이 서버를 통해 필터링 없이 그대로 HTML에 포함되어 출력될 경우 문제가 발생합니다.
예를 들어, 게시판에 다음과 같은 댓글이 작성되었다고 가정해봅니다.
<!-- 취약한 코드: 사용자 입력을 그대로 출력 -->
<p>댓글: <%= userInput %></p>
만약 userInput 값이 다음과 같이 입력된다면.
<script>alert('XSS');</script>
해당 페이지를 열람한 모든 사용자에게 경고창(alert)이 뜨게 됩니다. 이는 단순한 예시지만, 실제로는 쿠키를 탈취하거나, 악성 사이트로 리다이렉션 시키는 등 더 위험한 동작도 가능합니다.

C. 주요 XSS 유형 소개
XSS는 발생 위치와 동작 방식에 따라 다음과 같이 분류됩니다.
1. Reflected XSS (반사형)
- 공격자가 URL이나 폼 입력 등을 통해 전달한 악성 스크립트가 서버를 거쳐 즉시 응답으로 반영되는 형태입니다.
- 공격 링크를 이메일이나 메시지로 전파하는 방식이 많습니다.
2. Stored XSS (저장형)
- 악성 스크립트가 DB나 파일 등 서버에 저장된 후, 해당 데이터가 웹페이지에 출력될 때 실행됩니다.
- 게시판, 댓글, 프로필 정보 등에 자주 등장합니다.
3. DOM-based XSS
- 서버를 거치지 않고 클라이언트 측 자바스크립트 코드에서 발생하는 XSS입니다.
- URL 파라미터 등을 DOM에서 직접 읽고 HTML에 삽입할 경우 문제가 됩니다.
D. 왜 발생하는가?
XSS는 대부분 다음과 같은 이유로 발생합니다.
- "입력값에 대한 필터링 부족": 사용자로부터 받은 데이터를 신뢰하고 검증하지 않은 채 처리할 경우
- "출력 시 HTML 이스케이프 누락":
<,>,&,"같은 특수문자를 이스케이프하지 않고 HTML에 삽입할 경우
실무에서는 다음과 같은 구조에서 자주 발생합니다:
- 게시판 글, 댓글, 닉네임 등을 HTML로 출력할 때
- 검색 결과 페이지에서 검색어를 강조하여 표시할 때
- 클라이언트 자바스크립트에서
innerHTML,document.write등을 사용할 때
예제 코드: 취약한 코드와 안전한 코드 비교
취약한 코드 (Reflected XSS)
<!-- 서버에서 받은 query 값을 그대로 출력 -->
<p>검색어: <%= query %></p>
사용자가 다음과 같이 URL을 조작할 수 있습니다.
https://example.com/search?query=<script>alert('xss')</script>
안전한 코드
<!-- HTML 이스케이프 처리를 적용 -->
<p>검색어: <%= escapeHtml(query) %></p>
서버 또는 템플릿 엔진에서 HTML 특수문자를 변환하도록 설정해야 합니다.
// 예시: escapeHtml 함수 구현
function escapeHtml(str) {
return str
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/\"/g, """)
.replace(/'/g, "'");
}
참고 링크
- OWASP 공식 문서: https://owasp.org/www-community/attacks/xss
- MDN Web Docs (XSS): https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting