Skip to content

CSRF & XSS

웹 보안에서 자주 함께 언급되지만, 둘은 완전히 다른 공격이다.


CSRF

Cross-Site Request Forgery

사용자가 이미 로그인한 사이트에 대해, 공격자가 사용자의 브라우저를 이용해 의도하지 않은 요청을 보내게 만드는 공격이다.

즉, 서버 입장에서는 정상 사용자의 브라우저가 보낸 요청처럼 보일 수 있다.

성립 조건

  • 사용자가 대상 서비스에 로그인된 상태여야 한다.
  • 브라우저가 자동으로 인증 정보(예: 세션 쿠키)를 함께 보내야 한다.
  • 공격자가 사용자를 악성 페이지 또는 조작된 요청으로 유도해야 한다.

예시

  • 송금
  • 비밀번호 변경
  • 게시글 작성/삭제

이런 상태 변경 요청을 공격자가 대신 보내게 만드는 것이다.


대응 방법

1. CSRF 토큰 사용

서버가 예측 불가능한 토큰을 발급하고, 요청마다 이를 함께 검증하는 방식이다.

가장 일반적이고 강력한 방어 수단이다.

2. SameSite 쿠키 설정

세션 쿠키에 SameSite=Lax 또는 SameSite=Strict를 적용하면, 브라우저가 교차 사이트 요청에 쿠키를 덜 보내도록 제한할 수 있다.

다만 SameSite만으로 모든 경우를 막는다고 보면 안 된다.

3. Origin / Referer 검증

중요한 상태 변경 요청에서는 요청이 신뢰 가능한 출처에서 왔는지 확인할 수 있다.

실무에서는 Origin을 우선 보고, 없을 때 Referer를 보조적으로 확인하는 경우가 많다.

4. 안전한 HTTP 메서드 사용

GET, HEAD, OPTIONS, TRACE 같은 safe method로 상태를 변경하면 안 된다.

상태 변경은 POST, PUT, PATCH, DELETE처럼 의도가 분명한 메서드로 처리해야 한다.

5. 쿠키 기반 인증인지 확인

Authorization 헤더에 bearer token을 넣어 보내는 구조는, 브라우저가 자동으로 붙이는 쿠키 기반 인증보다 일반적으로 CSRF 영향이 작다.

하지만 XSS에 취약하면 다른 문제가 생기므로, "CSRF가 줄었다 = 안전하다"는 뜻은 아니다.


XSS

Cross-Site Scripting

공격자가 웹 페이지에 악성 스크립트를 삽입하거나 실행시켜, 피해자의 브라우저에서 원래 의도하지 않은 JavaScript가 실행되도록 만드는 공격이다.

대표 유형

  • Stored XSS: 악성 스크립트가 DB 등에 저장되고, 다른 사용자가 페이지를 볼 때 실행된다.
  • Reflected XSS: 요청 파라미터 같은 입력값이 즉시 응답에 반사되어 실행된다.
  • DOM-based XSS: 서버 응답이 아니라 클라이언트 측 DOM 조작 로직 때문에 실행된다.

피해 예시

  • 세션 탈취 시도
  • 사용자 대신 임의 동작 수행
  • 피싱 UI 삽입
  • 악성 스크립트 로드

HttpOnly 쿠키를 쓰면 쿠키 직접 읽기 위험은 줄일 수 있지만, XSS 자체를 막아주지는 못한다.


대응 방법

1. 출력 컨텍스트에 맞는 escaping

가장 중요하다.

  • HTML 본문
  • HTML 속성
  • JavaScript 문자열
  • URL

각 컨텍스트에 맞는 escaping 규칙이 다르다.

2. 사용자 입력을 HTML로 직접 렌더링하지 않기

가능하면 텍스트로 렌더링하고, 꼭 HTML 허용이 필요하다면 검증된 sanitizer를 사용한다.

3. CSP(Content Security Policy) 적용

인라인 스크립트, 임의 외부 스크립트 실행을 제한해 피해를 줄일 수 있다.

4. 최신 프레임워크의 기본 escaping 신뢰하되 우회 API 주의

React의 dangerouslySetInnerHTML, Vue의 v-html 같은 우회 API는 정말 필요한 경우에만 사용해야 한다.


자주 나오는 오해

CORS가 XSS를 막아주나?

아니다.

CORS는 "다른 origin의 응답을 읽을 수 있는지"를 제어하는 정책이지, 이미 현재 origin 안에서 실행된 악성 스크립트를 막는 장치는 아니다.

SOP가 있으면 CSRF/XSS가 끝나나?

아니다.

SOP는 읽기 제한에 강하지만, 브라우저가 자동으로 쿠키를 보내는 요청 자체를 완전히 막지 못하므로 CSRF와는 다른 문제다.


요약

  • CSRF는 사용자의 브라우저를 악용해 원치 않는 요청을 보내는 공격이다.
  • XSS는 사용자의 브라우저에서 악성 스크립트를 실행시키는 공격이다.
  • CSRF의 핵심 방어는 CSRF 토큰, SameSite, Origin/Referer 검증이다.
  • XSS의 핵심 방어는 escaping, sanitizing, CSP, 위험한 HTML 삽입 API 최소화다.