개념 사전 · 개념

XSS

Cross-Site Scripting · 크로스 사이트 스크립팅

는 신뢰할 수 없는 값이 브라우저에서 실행 가능한 HTML·스크립트 문맥으로 들어가는 취약점이다. 입력이 저장되었는지보다 어떤 출력 지점에서 어떤 파서가 해석하는지가 핵심이다.

밑줄 용어에 마우스를 올리거나, 키보드로 선택하거나, 터치하면 설명을 볼 수 있습니다.

01무엇이고, 어떤 일을 하나

  • 입력 부터 위험한 까지 데이터 흐름을 추적한다.
  • HTML·속성·URL·스크립트 문맥에 맞는 출력 방어를 선택한다.
  • 저장형·반사형·DOM 기반 경로를 구분해 재현 조건을 정한다.

02어떤 순서로 동작하나

  1. 값 획득

    서버나 브라우저가 요청·저장 게시물·URL·API 응답 등에서 값을 읽는다.

  2. 출력 문맥 선택

    값을 HTML 텍스트·속성·URL·스크립트 중 어디에 넣는지 결정한다. 문맥에 따라 필요한 처리가 달라진다.

  3. 안전한 자료 삽입

    단순 표시는 textContent로 넣고, 허용된 HTML이 필요하면 정화된 구조를 사용한다.

  4. 브라우저 해석

    innerHTML 같은 HTML 는 문자열을 요소 구조로 파싱한다. 실행 가능 여부는 실제 태그·속성·문맥과 정책에 달려 있다.

  5. 경로 검증

    응답 원문·최종 DOM·실행 위치를 비교한다. 저장형은 저장 뒤 다른 조회에서도 같은 경로가 이어지는지 확인한다.

03먼저 알아둘 용어와 구성요소

주소·메시지·응답 등 외부 데이터가 시작되는 지점.
innerHTML 등 데이터가 해석되거나 실행되는 출력 지점.
현재 파서에서 문법으로 쓰이는 문자를 데이터로 표현하는 처리.
허용한 HTML 구조를 남기고 위험한 요소·속성을 제거하는 처리.
저장된 입력이 다른 요청의 출력에서 실행되는 경로.
요청 입력이 같은 응답에 반영되어 실행되는 경로.
브라우저 측 코드의 자료 흐름에서 위험한 출력 해석이 일어나는 경로.
Content Security Policy; 브라우저가 허용할 자원·실행 정책을 제한하는 방어층.
LEARN THROUGH PRACTICE

반사 입력과 저장된 DOM을 서로 다른 경로로 읽기

브라우저 화면·DOM·저장 시점을 구분해 의 와 를 설명한다.

실습 구성과 전제

  • 자기 격리 에서 실제 계정 정보가 없는 전용 브라우저를 사용한다.
  • 아래 Reflected 페이지와 Stored 페이지는 서로 다른 과제 화면이므로 한 번의 실행 순서로 합치지 않는다.
  1. 입력이 어디서 화면으로 돌아오는지 찾는다

    • Reflected 과제에서는 폼 입력이 현재 응답에 반영되는 경로를 본다. 먼저 lab-marker 같은 무해한 문자열로 화면에 나타나는 위치를 기록한다.
    • 표시됐다는 사실만으로 코드 실행을 확정하지 않는다. HTML 소스와 DOM에서 텍스트인지 요소인지 확인한다.
    XSS · 설정·관리 화면 1원본 크기로 보기 ↗
    • 제목은 Reflected Cross Site Scripting이며 이름 입력칸과 Hello 출력 위치가 보인다.
    • 왼쪽에 Stored와 DOM 과제가 별도로 있어 유형이 다른 실습임을 구분할 수 있다.
    확인 기준

    현재 요청과 응답에서 입력이 반영되는 위치를 특정한다.

  2. 저장 폼과 DOM의 실행 문맥을 확인한다

    • Stored 과제에서는 입력이 저장된 뒤 다른 조회에서도 다시 렌더링되는지 본다. 재방문에 나타나는 것과 스크립트로 실행되는 것은 별도로 기록한다.
    • textarea의 maxlength 같은 브라우저 조건은 서버 출력 인코딩을 대신하지 않는다. 최종 가 HTML·속성·스크립트 중 무엇인지 결정해야 한다.
    XSS · 실습·개념 참고 화면 4원본 크기로 보기 ↗
    • DOM에 Stored Cross Site Scripting 제목과 POST guestform이 표시된다.
    • mtxMessage textarea의 maxlength가 1000으로 보인다. 길이 제한이 있어도 출력 문맥 처리가 필요하다.
    확인 기준

    저장 여부·출력 위치·실행 여부를 세 항목으로 나눈다.

  3. 텍스트 출력으로 같은 입력을 비교한다

    • 허용된 HTML이 필요하지 않은 영역은 textContent나 문맥에 맞는 출력 인코딩을 사용한다. HTML을 허용해야 한다면 정화 정책을 별도로 설계한다.
    • 문자열 '<b>lab</b>'를 예로 들어 요소로 렌더링하는 출력과 그대로 글자로 표시하는 출력을 비교한다.
    const value = '<b>lab</b>';
    output.textContent = value;

    교육용 DOM 비교 예시. 입력을 코드로 실행하지 않고 글자로 표시한다.

    확인 기준

    수정 후에는 정상 글자가 사라지지 않으면서 데이터가 실행 문맥을 만들지 않아야 한다.

실습에서 확인한 동작 원리

  • 반사·저장·DOM 경로는 입력의 이동 방식과 실행 시점을 나누는 기준이다.
  • 실제 방어는 최종 출력 문맥에 맞춰 적용한다.
관련 개념·전체 실습 화면 이어서 읽기 →
동작·명령 참고 문서

04예제로 따라가기

  • 요구 정의: 사용자가 입력한 제목은 A&B <C>라는 텍스트이며 태그나 엔터티 기능을 의도하지 않았다고 가정한다.
  • 텍스트 API: div 같은 일반 요소의 textContent에 원래 값을 넣으면 텍스트 노드가 되어 <C>가 HTML 요소로 파싱되지 않는다. script·style 요소에 신뢰할 수 없는 내용을 넣는 경우에 이 설명을 적용하면 안 된다.
  • HTML 문자열: 서버가 HTML 본문 문자열을 생성하는 경우 A&amp;B &lt;C&gt;처럼 해당 문맥에 맞게 표현한다.
  • 파싱 결과: HTML 파서는 엔터티를 문자로 해석하여 화면에 A&B <C>를 보여 준다. 엔터티가 풀렸다고 입력을 다시 HTML 코드로 실행하는 것은 아니다.
  • 이중 처리: 이미 인코딩된 &amp;를 다시 인코딩하면 &amp;amp;가 되어 화면에 &amp;가 남을 수 있다. 저장 형식과 출력 변환의 책임을 구분한다.

05혼동하기 쉬운 점과 확인 기준

  • 입력 출처: URL fragment·브라우저 저장소·메시지 이벤트처럼 서버 응답에 직접 나타나지 않는 를 추적한다.
  • 값의 변형: 디코딩·문자열 연결·템플릿 렌더링을 거쳐 어느 에 도달했는지 본다. 최종 화면만 보아서는 최초 입력 경로를 알기 어렵다.
  • 문맥 변화: HTML 텍스트용 인코딩을 ·CSS 문자열에도 공통 적용하지 않는다. 코드 문맥에 외부 값을 삽입하는 설계부터 줄인다.

06상세 노트 · 실습 자료

헤더 구조, 설정 예시, 수치 계산과 수업 캡처는 아래 노트에서 이어집니다.

READ · OBSERVE · CONNECT

함께 보는 학습 자료

아래 공식 자료를 본문의 개념·예제와 함께 읽어 보세요. 자료별로 확인할 위치와 관찰할 내용을 적었습니다.

공식 가이드

OWASP: HTML·속성·DOM 출력 문맥 비교

같은 입력도 삽입되는 파서 문맥에 따라 방어가 달라진다는 점을 예제별로 비교할 수 있다.

읽으면서 확인할 것
  • 일반 요소 textContent와 HTML 문자열 인코딩의 차이
  • 따옴표 있는 속성과 이벤트 처리기 속성의 차이
  • HTML·URL· 문맥에 필요한 별도 통제

공식 문서 · 표준

기초 개념과 동작 설명을 대조한 자료입니다. 제품 버전과 실제 설정에 따른 차이는 본문 및 원문에서 확인하세요.