정보보안핵심 · 14분 읽기

CSRF: 로그인된 브라우저의 요청 검증

CSRF는 브라우저가 자동으로 보내는 인증 정보를 악용해 원치 않는 행동을 유도하는 문제다. 요청의 출처와 사용자의 의도를 확인하는 통제가 필요하다.

개념부터 찾아보기

정의·역할·동작 원리를 독립 페이지에서 확인하세요. 본문의 밑줄 용어에도 설명이 있습니다.

이 노트에서 설명할 수 있게 되는 것

  1. 브라우저의 자동 쿠키 첨부가 만드는 신뢰 문제를 설명한다.
  2. CSRF 토큰의 생성·전달·검증 지점을 표시한다.
  3. 교차 사이트 요청·SOP·CORS를 서로 다른 판단으로 구분한다.

01개념과 구성 요소

  • 브라우저가 자동 첨부하는 인증 정보와 사용자가 의도한 요청은 같지 않다.
  • 외부 출처에서 요청을 만들 수 있고 인증 상태가 전달되며 서버가 별도 의도 검증 없이 상태를 바꿀 때 문제가 생긴다.
  • 세션에 연결한 토큰, 출처 검사, 적절한 쿠키 정책을 사용하며 민감 작업에는 추가 인증을 적용할 수 있다.

02Synchronizer Token으로 설정 변경을 처리하는 순서

  1. 서버가 인증된 세션에 연결된 예측하기 어려운 토큰을 정상 폼에 제공한다.
  2. 브라우저가 폼 값·토큰과 쿠키 정책에 맞는 인증 쿠키를 보낸다.
  3. 서버가 세션 유효성, 토큰 존재·일치·세션 연결을 확인한다. 쿠키에 토큰이 자동 첨부된다는 사실만으로는 충분하지 않다.
  4. 현재 사용자에게 변경 권한이 있고 값이 업무 규칙을 만족하는지 확인한다.
  5. 앞선 검증을 통과한 경우에만 변경한다. 오류 응답 전에 DB 변경을 먼저 수행하면 거부가 실제 보호가 되지 않는다.

03서버가 받은 요청과 사용자의 의도는 같지 않을 수 있다

  • 로그인 후 브라우저는 대상 서비스에 맞는 쿠키를 자동으로 첨부한다. 다른 사이트에서 폼 제출·링크 이동·자원 로딩으로 그 서비스에 요청을 만들 수 있고 쿠키 정책상 인증 쿠키가 함께 전송되면 서버는 로그인한 사용자를 식별한다.
  • 하지만 그 행동을 사용자가 의도했는지는 쿠키만으로 알 수 없다.
  • 는 이 자동 인증 상태를 이용하는 문제다. 공격자가 쿠키 값을 직접 훔쳐야만 성립하는 것은 아니고, 대상 사이트 안에 스크립트를 미리 저장할 필요도 없다.
  • 공격자가 응답 본문을 읽지 못해도 계정 설정이나 주문 상태가 서버에서 바뀌었다면 영향은 이미 발생했다.

04정상 폼이 상태를 바꾸는 순서

  • 일반적인 설정 변경에서는 사용자가 폼을 요청하고 서버가 현재 값을 보여 준 뒤 제출된 새 값을 처리한다. 서버 측 세션을 쓰는 방식은 예측하기 어려운 값을 세션과 연결하고 정상 폼의 숨은 필드 등에 넣는다.
  • 제출 때는 인증 상태, 토큰의 존재·일치·세션 연결, 권한과 값의 유효성을 확인한 후 변경한다.
  • 토큰이 단순히 요청에 있다는 사실보다 서버가 어떤 기준과 비교하는지가 중요하다. 토큰을 쿠키에만 넣고 브라우저가 자동 첨부하는지 보기만 하면 세션 쿠키와 같은 한계를 반복한다.
  • 또한 토큰은 사용자의 내심을 증명하는 것이 아니라 외부 사이트가 모르는 요청 문맥을 검증하는 보호 장치다.
html
<form action="/training/preferences" method="post">
  <input name="theme" value="dark">
  <input type="hidden" name="csrf_token" value="<가상 토큰>">
  <button type="submit">저장</button>
</form>

서버 흐름:
세션 확인 → 토큰 비교 → 권한·입력 검증 → 변경 → 결과 응답

비밀번호나 결제 대신 가상 화면 설정을 사용하는 정상 토큰 폼 예제다.

05One-click·자동 자원 요청·POST를 구분하기

  • 링크를 클릭하면 대상 URL로 탐색하며 GET 요청이 발생할 수 있다. img 같은 요소는 사용자가 별도의 버튼을 누르지 않아도 문서를 표시하는 과정에서 자원을 요청한다.
  • 대상이 GET 요청으로 상태를 바꾸도록 설계되었다면 단순 자원 요청도 업무 변경에 연결될 수 있다. 이는 렌더링 엔진이 임의 코드를 몰래 실행해서가 아니라 정상적인 자원 요청의 부작용이다.
  • POST로 바꾸는 것만으로 가 자동 해결되지는 않는다. 외부 사이트도 브라우저가 허용하는 폼 제출을 만들 수 있기 때문이다.
  • HTTP 메서드의 의미에 맞게 GET을 조회 중심으로 유지하는 것과 요청에 적절한 검증을 적용하는 것은 함께 필요한 설계다.

06출처·사이트·CORS가 서로 다른 이유

  • 은 스킴·호스트·포트로 구분한다. 쿠키 의 사이트 판단은 이와 같지 않아 하위 도메인이나 포트 차이가 있더라도 두 판단이 같은 결과라고 단정할 수 없다.
  • =Strict, Lax, None은 교차 사이트 조건에서의 쿠키 전송을 서로 다르게 제한한다. 실제 브라우저의 쿠키 정책과 사용 흐름도 영향을 준다.
  • CORS는 브라우저 가 다른 출처의 응답에 접근하는 조건과 관련된다. 단순 요청처럼 서버에 먼저 도달할 수 있는 경로가 있어 CORS 오류가 뜬 사실만으로 서버가 요청을 받지 않았다고 결론 내릴 수 없다.
  • 미리 확인하는 preflight가 필요한 요청과 그렇지 않은 요청도 구분해야 한다. 에서는 응답 열람보다 이 핵심일 수 있다.

07세션 토큰 방식과 Double Submit의 차이

  • 은 서버 측 세션에 연결된 값을 요청의 별도 위치로 되돌려 받아 비교한다. 요청별 토큰은 재사용 범위를 줄일 수 있지만 여러 탭이나 뒤로 가기와의 상호작용이 생길 수 있다.
  • 세션 단위 토큰도 예측 불가능성과 올바른 연결·검증이 핵심이다.
  • 은 쿠키와 요청의 별도 필드에 실린 값을 비교하는 계열이다. 단순 동일값 비교를 아무 조건 없이 안전하다고 일반화하면 쿠키 주입 같은 문제가 남을 수 있다.
  • 서명과 세션 연결을 포함한 검토된 패턴을 사용해야 하며, 프레임워크가 제공하는 보호를 임의로 약화시키지 않는 것이 중요하다. API가 헤더 기반 인증을 사용하는 경우에도 어떤 값이 자동 전송되고 외부 출처가 그 헤더를 만들 수 있는지 위협 모델을 다시 읽는다.
  1. 방식은 쿠키의 값과 별도로 요청에 제출될 값을 마련한다.
  2. 정상 페이지가 폼 필드 또는 요청 헤더에 값을 넣어 보낸다. 자동 첨부 쿠키만 존재하는 요청과 구분한다.
  3. 서버가 제출값과 쿠키값 및 설계한 서명·세션 연결을 검증한다.
  4. 일치와 연결 조건을 통과한 뒤에만 ·입력 검증을 거쳐 상태를 변경한다. 쿠키 주입이 가능한 환경의 단순 값 비교는 충분하지 않을 수 있다.

08Origin·Referer와 쿠키 속성의 역할

  • 서버는 요청의 또는 정책에 맞는 Referer 정보를 대상 서비스와 비교하여 외부 출처 요청을 제한할 수 있다. 값의 부분 문자열만 비교하면 신뢰하지 않는 이름이 허용된 이름을 포함하는 경우를 잘못 받아들일 수 있으므로 정확한 출처 해석이 필요하다.
  • 헤더 누락·프록시의 외부 주소와 내부 주소 차이는 명시적인 정책으로 다뤄야 한다.
  • Secure는 안전한 전송 조건을, HttpOnly는 스크립트의 쿠키 읽기를 제한한다. 둘 자체는 브라우저가 정상적으로 인증 쿠키를 붙인 요청을 서버가 처리하는 문제를 해결하지 않는다.
  • 도 추가 방어 층이지만 모든 동작과 환경의 토큰을 무조건 대체하는 스위치는 아니다.
원리 심화

09Fetch Metadata와 토큰을 조합하는 요청 정책

  • Sec-Fetch-Site는 ··cross-site·none 등 요청 문맥을 알려 준다. 사이트 관계가 사용자 의도나 업무 권한을 직접 증명하지는 않는다.
  • 라도 다른 하위 도메인을 신뢰할 수 없다면 변경 요청을 일괄 허용해서는 안 된다. 의 스킴·호스트·포트와 정책을 함께 본다.
  • 상태를 바꾸는 메서드·엔드포인트에 토큰과 출처 검증을 적용한다. 조회 요청처럼 보이는 GET이 실제 변경을 수행하면 보호 가정이 깨진다.
  • 일부 클라이언트는 를 보내지 않는다. 이 경우 토큰· 같은 대체 검증을 어떻게 적용할지 명시해야 한다.
  • 토큰은 인증 세션과 검증 정책에 연결되어야 한다. 요청 값과 쿠키 값이 같다는 사실만으로 신뢰 경계를 완성하지 않는다.
예제로 추적

10가상 이메일 변경 요청 네 가지의 판정

  1. 유효 세션·허용 ·일치하는 토큰을 가진 요청은 새 주소 형식과 업무 권한까지 검증한 뒤 변경한다.
  2. 같은 세션 쿠키를 보내도 토큰이 없으면 변경 전에 거부한다. 인증 성공과 변경 의도 검증 실패가 동시에 존재할 수 있다.
  3. 토큰 없이 cross-site로 들어온 요청은 정책상 거부한다. 브라우저가 응답을 읽지 못하더라도 변경이 발생하면 보호에 실패한 것이다.
  4. 토큰이 회전한 뒤 이전 탭이 제출한 값은 정책에 따라 거부될 수 있다. 이때 데이터 변경 없이 다시 불러오도록 안내한다.
  5. 상태 코드·거부 이유·DB 변경 여부를 함께 본다. 거부 응답을 보낸 뒤 내부 변경이 이미 발생한 구현은 순서가 잘못되었다.
검증·예외

11CSRF 오탐과 우회 경계의 진단

  • 문자열 접미사 포함 여부 대신 파싱한 스킴·호스트·포트를 정확히 비교한다. 신뢰 프록시의 외부 URL 전달 설정도 함께 확인한다.
  • 요청마다 토큰을 즉시 폐기하는 정책은 뒤로 가기·재시도·동시 탭과 충돌할 수 있다. 보안 요구와 허용 수명을 명시한다.
  • CORS 허용은 응답 읽기 정책이다. 단순 요청의 전송·서버 처리 자체를 모두 차단하는 방어로 가정하지 않는다.
  • 같은 의 코드 실행이 가능하면 공격자가 토큰을 읽거나 정상 요청을 만들 수 있다. 와 의 시험 범위를 별도로 유지한다.

12XSS와 결합되면 보호의 전제가 달라진다

  • 는 일반적으로 다른 사이트에서 인증된 브라우저를 이용해 요청을 만든다. 는 대상 출처에서 코드가 실행되는 경계를 침해한다.
  • 같은 출처의 코드가 정상 페이지의 토큰을 읽고 요청을 보낼 수 있다면 외부 출처가 토큰을 모른다는 보호의 전제가 약해진다.
  • 둘의 결과가 모두 설정 변경일 수 있어도 취약점 분류는 요청을 만든 원인과 실행 문맥을 기준으로 한다. 강제 로그아웃도 단순 외부 자원 요청으로 가능한지, 주입된 가 실행되어 발생했는지에 따라 설명이 달라진다.
  • 방어와 방어를 함께 다뤄야 하는 이유는 같은 이름의 공격이어서가 아니라 서로의 경계를 침해할 수 있기 때문이다.

13토큰 오류가 났을 때 실제로 멈춰야 하는 단계

  • 학습 비교에서는 정상 토큰, 누락 토큰, 다른 세션 토큰, 만료된 세션을 나누고 여부를 본다. 토큰 오류 응답을 내면서 DB 변경을 먼저 수행했다면 화면상 거부와 서버 상태가 다르다.
  • 변경은 인증·토큰·권한 검증 뒤에 있어야 하며 내부 로그에는 판단 단계와 요청 ID를 연결한다.
  • 로그인 요청, 파일 업로드, 비밀번호 재설정과 연동 해제처럼 일반 게시물 폼과 다른 경로도 상태 변화를 만든다. 민감한 작업은 재인증 등 추가 조건이 필요할 수 있다.
  • 학습의 목적은 토큰 문자열을 암기하는 것이 아니라 정상 페이지 발급→요청 반환→서버 검증→변경이라는 순서가 어떻게 요청 위조를 제한하는지 설명하는 데 있다.

설명과 함께 보는 보조 도식

메시지 순서

모식도 · 세션 연결 CSRF 토큰

자동 전송되는 쿠키와 명시적으로 제출하는 토큰의 역할을 구분한다.

정상 브라우저업무 서버세션 상태1. 토큰 연결2. 정상 화면 제공3. 변경 요청4. 일치 검사5. 결과 응답
전체 단계를 한 번에 읽기
  1. 01

    토큰 연결

    세션에 검증할 토큰 상태를 연결한다.

  2. 02

    정상 화면 제공

    클라이언트가 상태 변경에 사용할 토큰을 전달한다.

  3. 03

    변경 요청

    쿠키와 별도로 지정 위치에 토큰을 포함한다.

    입력
    세션 + CSRF 토큰
  4. 04

    일치 검사

    요청 토큰과 유효 세션의 관계를 검증한다.

    실패
    변경 거부
  5. 05

    결과 응답

    정책을 만족한 요청만 처리하고 결과를 반환한다.

메시지와 상태 변화를 단순화한 학습용 모식도입니다. 생략한 메시지와 예외는 본문의 설명을 함께 확인하세요.
LEARN THROUGH PRACTICE

쿠키가 동반된 상태 변경 요청을 패킷에서 읽기

정상 로그인 상태가 사용자의 변경 의도를 증명하지 않는다는 점을 실제 요청 구조로 설명한다.

실습 구성과 전제

  • 격리 의 폐기 가능한 계정으로만 을 시험한다.
  • 사진 속 요청과 테스트 값은 당시 교육 환경의 기록이다. 자신의 환경에서는 새 토큰과 무해한 변경 항목을 사용한다.
  1. 상태 변경을 유발하는 입력 위치를 찾는다

    • 사진의 폼은 게시 메시지 안에 다른 기능을 향하는 링크를 넣은 사례다. 메시지 저장과 링크 목적지의 은 서로 다른 요청이다.
    • 링크를 봤다는 것·눌렀다는 것·서버가 변경을 수락했다는 것을 각각 구분한다.
    7/20 · 실습·개념 참고 화면 2원본 크기로 보기 ↗
    • URL-encoded 폼의 mtxMessage에 링크가 들어가며 별도의 변경 기능 경로를 가리킨다.
    • 버튼 값은 Sign Guestbook이다. 겉으로 보이는 게시 기능과 링크의 목적 기능이 다르다.
    확인 기준

    이 첫 화면은 입력 저장 요청이며 계정 변경 성공의 증거는 아니다.

  2. 자동으로 붙는 인증 자료를 확인한다

    • 다음 캡처에는 변경 기능을 향한 GET과 Cookie가 함께 보인다. 브라우저가 인증 자료를 첨부해도 사용자가 그 변경을 의도했다고 증명할 수는 없다.
    • GET은 안전한 조회 의미로 설계해야 하며, 을 GET에 맡기지 않는다. 메서드를 POST로 바꾸는 것만으로 가 해결되는 것도 아니다.
    7/20 · 실습·개념 참고 화면 3원본 크기로 보기 ↗
    • 요청 행은 비밀번호 변경 기능을 향한 GET이고 Cookie 헤더가 포함된다.
    • Referer는 다른 과제 페이지를 나타내며 Response in frame 링크가 제공된다. 실제 변경 판정에는 대응 응답과 계정 상태가 더 필요하다.
    확인 기준

    응답 메시지뿐 아니라 서버 상태가 바뀌었는지 확인한다.

  3. 의도 검증 실패가 변경 전에 끝나는지 시험한다

    • 정상 토큰·누락 토큰·다른 세션 토큰으로 요청을 구분한다. 토큰 검증 실패는 실제 변경 코드가 실행되기 전에 거부돼야 한다.
    • ··는 보조 조건이며 배포 환경의 정상 요청과 함께 시험한다.
    확인 기준

    누락·불일치 토큰 요청 뒤 계정 정보가 그대로인지까지 확인한다.

실습에서 확인한 동작 원리

  • 인증된 요청과 의도된 요청은 다르다.
  • 거부 화면이 아니라 변경이 수행되지 않았다는 상태 증거가 필요하다.

설정·출력 추가로 확인하기 6장

아래 화면을 펼쳐 위 실습의 설정값, 명령과 확인 기준을 비교해 보세요. 각 묶음은 별도 실습 기록입니다.

실습 화면 묶음 01 1장
0722 발표 · 패킷 캡처 7원본 크기로 보기 ↗
  • 문서 문맥에 삽입된 원본 패킷 캡처이다. CSRF 학습 내용과 함께 당시 구성·설정·관찰 결과를 비교할 수 있다.
실습 화면 묶음 02 2장
7/20 · 실습·개념 참고 화면 4원본 크기로 보기 ↗
  • 「CSRF」 문맥에 삽입된 원본 실습·개념 참고 화면이다. CSRF 학습 내용과 함께 당시 구성·설정·관찰 결과를 비교할 수 있다.
7/20 · 실습·개념 참고 화면 5원본 크기로 보기 ↗
  • 문서 문맥에 삽입된 원본 실습·개념 참고 화면이다. CSRF 학습 내용과 함께 당시 구성·설정·관찰 결과를 비교할 수 있다.
실습 화면 묶음 03 3장
7/30 - 발표 · 실습·개념 참고 화면 31원본 크기로 보기 ↗
  • 「3. 피해자 역할 브라우저에서 확인」 문맥에 삽입된 원본 실습·개념 참고 화면이다. CSRF 학습 내용과 함께 당시 구성·설정·관찰 결과를 비교할 수 있다.
7/30 - 발표 · 실습·개념 참고 화면 32원본 크기로 보기 ↗
  • 「3. 피해자 역할 브라우저에서 확인」 문맥에 삽입된 원본 실습·개념 참고 화면이다. CSRF 학습 내용과 함께 당시 구성·설정·관찰 결과를 비교할 수 있다.
7/30 - 발표 · 실습·개념 참고 화면 33원본 크기로 보기 ↗
  • 「3. 피해자 역할 브라우저에서 확인」 문맥에 삽입된 원본 실습·개념 참고 화면이다. CSRF 학습 내용과 함께 당시 구성·설정·관찰 결과를 비교할 수 있다.
동작·명령 참고 문서
READ · OBSERVE · CONNECT

함께 보는 학습 자료

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

공식 가이드

OWASP: CSRF token과 출처 검증

인증 쿠키가 있는 요청과 사용자가 의도한 요청의 차이를 token·· 조건으로 설명한다.

읽으면서 확인할 것
  • 검증과 의 선후 관계
  • 의 한계와 · 구분
  • ·Referer 검증에서 기대한 출처를 정하는 방법
학습 확인

이해했는지 확인하기

  • 상태 변경 기능이 GET 요청에 의존하지 않는지 확인한다.
  • 토큰이 없거나 틀린 요청이 실제로 거부되는지 확인한다.
  • SameSite·Origin 검사·XSS 방어의 역할을 구분한다.

함께 확인할 공식 자료