Blog
XSS란 무엇인가: 브라우저에서 실행되는 공격
서론#
웹 애플리케이션 보안 취약점 중 XSS는 가장 오래되었지만,
여전히 실제 서비스에서 자주 발견되는 문제다.
이 글에서는 XSS가 무엇인지, 왜 위험한지에 집중한다.
XSS란?#
Cross-Site Scripting은 약자로 쓰면 CSS가 되지만,
이미 **Cascading Style Sheets(CSS)**가 존재하기 때문에
혼동을 피하기 위해 XSS라는 약어를 사용한다.
XSS는 공격자가 **의도하지 않은 스크립트(JavaScript)**를 웹 페이지에 주입하여, 다른 사용자의 브라우저에서 실행되도록 만드는 공격이다.
중요한 점은 다음 한 줄이다.
XSS는 서버를 공격하는 것이 아니라, 사용자의 브라우저를 공격한다.
즉, 서버는 정상 동작하고 있어도
브라우저에서 실행되는 순간 이미 보안은 깨진 상태이다.
XSS가 가능한 이유#
웹 애플리케이션은 본질적으로 다음을 반복한다.
- 사용자의 입력을 받는다.
- 그 입력을 가공한다.
- 화면에 다시 출력한다.
이 과정에서 "입력값이 코드가 아닌 데이터라는 보장"이 깨지는 순간
XSS 취약점이 발생한다.
예를 들어, 사용자가 입력한 값이 단순 문자열이 아니라
브라우저가 스크립트로 해석할 수 있는 형태로 렌더링되면 문제가 된다.
XSS의 핵심 위험#
XSS가 위험한 이유는 단순히 alert를 띄울 수 있어서가 아니다.
공격자는 다음을 할 수 있다.
- 사용자의 인증된 권한으로 요청을 실행
- 페이지 내용을 조작하거나 피싱 UI 삽입
- 키 입력 가로채기
- 사용자를 다른 악성 사이트로 리다이렉트
즉, 로그인한 사용자가 자신의 권한으로 직접 악성 코드를 실행한 것과 동일한 상태가 된다.
XSS의 기본 분류#
XSS는 공격 코드가 어디에 저장되고, 언제 실행되느냐에 따라 나뉜다.
1. Stored XSS (저장형 XSS)#
- 공격 코드가 DB 등에 저장
- 이후 해당 데이터를 조회하는 모든 사용자에게 실행
- 게시글, 댓글, 프로필 소개글 등에서 자주 발생
2. Reflected XSS (반사형 XSS)#
- 공격 코드가 요청(Request)에 포함
- 서버 응답에 그대로 반사되어 실행
- 검색어, 쿼리 파라미터 처리에서 자주 발생
3. DOM-based XSS#
- 서버는 개입하지 않음
- 브라우저에서 DOM 조작 중 발생
- innerHTML, document.write, location, eval 등 사용 시 자주 발생
XSS는 "옛날 취약점"이 아니다#
XSS는 오래된 공격 기법이지만,
아직까지도 매우 흔한 취약점이다.
-
Zoom(2020): Zoom 웹 클라이언트의 지속형 XSS 결함을 악용한 공격자가 채팅을 통해 악성 코드를 주입할 수 있었습니다. 빠르게 패치되었지만 이로 인해 Zoom의 보안 우려가 가중되어, 보안 강화에 집중하기 위해 90일간 기능 사용을 중단해야 했습니다.
-
WordPress WPBakery Page Builder 플러그인(2020): WPBakery의 Page Builder 플러그인에 발생한 저장형 XSS 결함으로 인해 공격자가 수천 개의 WordPress 사이트에 악성 스크립트를 주입할 수 있었습니다. 대량 훼손, 잠재적인 데이터 도용, 긴급 패치로 인해 다운타임과 재정적 손실이 발생하여 플러그인의 평판이 손상되었습니다.
-
Slack(2021): Slack의 공유 작업 공간 초대장에 저장형 XSS 취약성이 발생한 결과, 공격자는 스크립트를 삽입하여 토큰을 도용하거나 설정을 변경할 수 있게 되었습니다. Slack은 긴급 수정 사항을 발표했지만, 기업 고객들은 더 강력한 보안 조치를 요구하며 일주일 동안 엔지니어링 리소스를 분산 운영했습니다.
-
Atlassian Confluence(2021): Confluence의 지속형 XSS 취약성으로 인해 특정 권한을 가진 사용자가 세션을 가로채는 악성 매크로를 삽입할 수 있었습니다. 조직들은 승인되지 않은 Wiki 편집 사례를 보고했고, Atlassian은 긴급 패치를 배포하고 기업들은 긴급 업데이트를 실시해야 했습니다.
정리#
- XSS는 브라우저에서 실행되는 공격이다.
- "입력 > 출력" 흐름이 있는 곳이면 어디든 발생할 수 있다.
- 서버가 안전해 보여도 프론트에서 취약점이 생길 수 있다.
- 단순한 UI 문제가 아니라 권한 탈취 수준의 보안 문제다.
참조#
관련 게시글
5개
Next.js에서 보안 헤더를 설정한다는 것의 의미와 한계
Next.js에서 설정할 수 있는 보안 헤더들의 역할과 한계를 정리합니다. 보안 헤더가 무엇을 막아주지 않는지, 프레임워크와 개발자의 책임 경계를 중심으로 설명합니다.
React는 왜 기본적으로 XSS에 강할까?
React가 XSS에 강해 보이는 이유를 렌더링 방식 관점에서 설명하고, dangerouslySetInnerHTML, 속성 기반 주입, DOM 직접 조작 시 다시 취약해지는 지점을 정리합니다.
NEXT_PUBLIC_ 환경변수는 왜 env인데 클라이언트에 노출될까
NEXT_PUBLIC_ 환경변수가 왜 클라이언트 번들에 포함되는지, env는 언제 비밀이 되고 언제 설정값이 되는지 Next.js 빌드 구조와 보안 기준으로 정리합니다.
innerHTML을 사용할 때 조심해야 하는 이유
innerHTML이 왜 보안상 주의가 필요한 API인지, XSS 취약점과 안전한 대체 방법(textContent, sanitize)을 통해 정리합니다.
env는 보안인가? 많은 개발자들이 착각하는 이유
env는 보안 기능일까? 이 글에서는 env의 역할과 한계, NEXT_PUBLIC_ 환경 변수의 노출 특성, 프론트엔드에서 노출돼도 되는 값의 기준을 정리합니다.