XSS 공격 유형과 웹 애플리케이션 방어 전략

저장형·반사형·DOM 기반 XSS의 동작 방식과 세션 탈취, 사이트 변조 피해를 줄이기 위한 웹 보안 대응 전략

2026-08-14 · 최초 발행 2025-05-29

브라우저에서 실행되는 입력값이 만드는 문제

XSS(Cross-Site Scripting)는 공격자가 웹 페이지에 악성 클라이언트 측 스크립트를 삽입하고, 다른 사용자의 브라우저에서 이를 실행하게 만드는 공격이다. 사용자는 특정 웹사이트에 접속했을 뿐인데도 스크립트 실행을 인지하지 못할 수 있다.

이 공격은 사용자의 개입 없이 브라우저에서 실행될 수 있으며, 개인정보 탈취나 세션 하이재킹처럼 목적이 분명한 공격으로 이어질 수 있다. 저장형 XSS는 특히 장기간 영향을 남길 수 있고, 기술 지식이 부족한 일반 사용자도 주요 표적이 된다.

악성 스크립트가 전달되는 경로

서버에 남는 저장형 XSS

저장형 XSS(Stored/Persistent XSS)는 악성 스크립트가 웹 서버에 영구적으로 저장되는 유형이다. 게시글이나 댓글처럼 서버에 보관되는 데이터에 스크립트가 들어가면, 해당 페이지를 방문하는 모든 사용자가 영향을 받을 수 있다.

희생자웹 서버/DB공격자희생자웹 서버/DB공격자희생자 브라우저에서 악성 스크립트 실행악성 스크립트가 포함된 데이터 제출 (게시글, 댓글 등)악성 스크립트 저장페이지 요청악성 스크립트가 포함된 페이지 전송

2005년 MySpace에서 발생한 'Samy 웜'은 저장형 XSS의 대표 사례다. 이 웜은 24시간 만에 백만 명 이상의 사용자에게 영향을 미쳤다.

요청과 응답 사이에 섞이는 반사형 XSS

반사형 XSS(Reflected XSS)는 공격자가 만든 악성 링크를 사용자가 클릭했을 때 발생한다. 요청에 포함된 값이 서버 응답에 반영되면서 악성 스크립트가 실행된다.

웹 서버희생자공격자웹 서버희생자공격자희생자 브라우저에서 악성 스크립트 실행악성 URL 전송 (이메일, 메시지 등)악성 URL 요청악성 스크립트가 포함된 응답 반환

예를 들어 http://vulnerable-site.com/search?q=<script>악성코드</script> 같은 URL을 통해 검색 결과 페이지에 스크립트가 주입될 수 있다.

클라이언트 DOM 처리에서 생기는 XSS

DOM 기반 XSS(DOM-based XSS)는 HTML 문서의 DOM 구조를 변경하는 클라이언트 측 스크립트의 취약점을 이용한다. 서버 측 코드가 아니라 클라이언트 측 JavaScript에서 취약점이 발생한다는 점이 앞선 유형과 다르다.

브라우저희생자공격자브라우저희생자공격자서버와 통신 없이 클라이언트에서 발생악성 URL 전송URL 접속DOM 처리 중 악성 스크립트 실행

웹 페이지가 document.location.hash 값을 적절히 검증하지 않은 채 innerHTML에 할당하면 이 취약점이 발생할 수 있다.

사용자 권한을 악용하는 피해

XSS가 성공하면 쿠키 정보와 세션 ID를 획득해 세션 하이재킹으로 이어질 수 있다. 자동 로그인 정보나 브라우저에 저장된 개인정보도 탈취 대상이 된다.

공격자는 사용자 권한으로 웹사이트를 조작하거나 거래를 수행할 수 있다. 악성 코드 다운로드를 유도하고, 피싱을 위한 위조 로그인 페이지를 제시하는 방식도 가능하다. 페이지 콘텐츠를 바꿔 사용자 경험을 떨어뜨리고 사이트 신뢰도를 손상시키는 피해도 발생한다.

애플리케이션에서 차단할 지점

입력값 검증만으로는 충분하지 않다. 데이터가 HTML에 출력되는 문맥에 맞춰 인코딩하고, 브라우저에서 위험한 실행 경로를 줄여야 한다.

// 잘못된 방식 (취약점)
element.innerHTML = userProvidedData;

// 올바른 방식 (안전)
element.textContent = userProvidedData; // 또는
element.innerText = userProvidedData;

특수문자를 HTML 엔티티로 변환하는 방식은 다음과 같다.

function escapeHTML(str) {
  return str.replace(/[&<>"']/g, function (match) {
    switch (match) {
      case "&":
        return "&amp;";
      case "<":
        return "&lt;";
      case ">":
        return "&gt;";
      case '"':
        return "&quot;";
      case "'":
        return "&#39;";
    }
  });
}

Microsoft의 AntiXSS 라이브러리, OWASP ESAPI(Enterprise Security API), DOMPurify와 js-xss 등의 JavaScript 라이브러리도 활용할 수 있다.

콘텐츠 보안 정책(CSP)은 HTTP 헤더로 스크립트 실행 범위를 제한하는 수단이다.

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com;

쿠키에는 HttpOnly 플래그를 설정해 JavaScript를 통한 접근을 막고, Secure 플래그로 HTTPS 연결에서만 전송되도록 할 수 있다. SameSite 속성은 CSRF 공격 방지에 도움을 준다.

Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict

중요 정보는 쿠키에 저장하지 않고, 세션 ID에는 충분한 복잡성과 무작위성을 보장해야 한다.

사용자가 줄일 수 있는 노출

브라우저에는 최신 보안 업데이트를 적용하고, 취약점 패치가 포함된 최신 버전을 사용한다. JavaScript 실행 제한 설정을 활성화하거나 신뢰할 수 있는 사이트에서만 스크립트 실행을 허용하는 것도 방어에 도움이 된다.

의심스러운 이메일이나 메시지의 링크는 클릭을 자제하고, 방문 전 URL을 확인해야 한다. 광고 차단 및 스크립트 차단 확장 프로그램을 사용할 수 있으며, NoScript와 uBlock Origin도 활용 대상이다.

사건이 남긴 경고

2010년 트위터에서는 사용자가 특정 트윗 위에 마우스를 올리면 자동으로 리트윗되는 웜이 확산됐다. onMouseOver 이벤트를 활용한 공격으로 수십만 사용자에게 영향을 미쳤다.

2013년 야후 메일의 XSS 취약점은 공격자가 사용자 쿠키를 탈취하고 계정에 접근할 수 있게 했다. 2014년에는 eBay의 일부 제품 목록 페이지에 악성 JavaScript가 삽입돼 사용자 개인정보를 탈취하는 공격이 발생했다.

XSS는 오래된 공격 기법이지만 여전히 OWASP Top 10에 포함되는 보안 위협이다. 웹 애플리케이션이 복잡해지고 클라이언트 측 기술 사용이 늘면서 새로운 형태의 XSS 취약점도 계속 발견되고 있다.

XSS웹 보안입력 검증CSP세션 하이재킹