Stored 크로스 사이트 스크립팅 (Stored XSS)

Stored Cross-Site Scripting (Stored XSS)

설명

Stored XSS는 파일 시스템, DB 등 저장소에 있던 값(예: 파일명, 게시글 제목)을 적절한 출력 인코딩 없이 HTML로 렌더링할 때 발생합니다. 공격자는 악성 스크립트를 포함한 값을 저장해두고, 해당 값이 나중에 페이지에 표시될 때 스크립트가 자동 실행되도록 악용할 수 있습니다. 예를 들어, 악성 파일명을 업로드한 뒤 디렉터리 목록을 보여주는 페이지에서 그 이름을 그대로 HTML에 삽입하면 피해자가 목록을 열람하는 순간 스크립트가 실행됩니다.

잠재적 영향

  • 세션 탈취: 악성 스크립트가 document.cookie 등을 탈취해 로그인 세션을 가로챌 수 있음

  • 계정 탈취/권한 남용: 관리자 계정 접수, 사용자의 권한으로 임의 액션 수행 가능

  • 피싱/페이지 변조: 화면 조작, 가짜 입력창 삽입으로 사용자 기만 및 민감정보 수집

  • CSRF 유도 및 내부 자원 접근: 사용자의 브라우저 권한을 악용해 내부 API 호출, 상태 변경 수행

  • 지속성 있는 감염: 저장소에 남아 다수 사용자에게 반복적으로 악성 스크립트를 실행

해결 방법

  • 출력 인코딩: HTML 콘텐츠에 값을 넣기 전, 컨텍스트에 맞는 인코딩/이스케이프(HTML 엔티티 인코딩, 속성 컨텍스트, URL 컨텍스트 등)를 적용하세요.

  • 템플릿 엔진 자동 이스케이프 사용: ejs/pug/nunjucks 등의 기본 이스케이프 기능을 끄지 말고, 신뢰되지 않은 값을 문자열 연결로 직접 HTML에 삽입하지 마세요.

  • 안전한 응답 포맷: 가능하면 res.json 등 스크립트 실행과 직접 연결되지 않는 포맷으로 전달하세요.

  • 입력 검증 및 정규화: 파일명 등 저장 전 단계에서 허용 문자(화이트리스트)를 적용하고, 스크립트 관련 메타문자(<, >, ", ', &, / 등)를 제한하세요.

  • 보안 헤더: CSP(Content-Security-Policy), X-Content-Type-Options, HTTPOnly/Secure/SameSite 쿠키로 피해 범위를 줄이세요.

  • 라이브러리 사용: escape-html, he, validator 등 검증된 라이브러리로 인코딩/필터링을 구현하세요.

취약한 코드 및 안전한 코드 예시

취약한 코드

안전한 코드

설명:

  • 취약한 코드: 파일 시스템에서 읽은 파일명(names)이 신뢰되지 않은 데이터인데, 이를 HTML 문자열에 그대로 연결하여 res.send로 전송합니다. 공격자가 또는 등 태그를 포함한 파일명을 저장해두면, 목록 페이지를 열람하는 사용자의 브라우저에서 스크립트가 실행되어 저장형 XSS가 발생합니다.

  • 안전한 코드: escape-html(또는 he/validator 등)을 사용해 파일명을 HTML 엔티티로 인코딩하여 브라우저가 태그로 해석하지 못하게 합니다. 또한 JSON 응답을 활용해 스크립트 실행 컨텍스트와 분리하는 대안을 제공하여 XSS 위험을 줄입니다.

참조

Last updated