1일 1CS(Computer Science)

CSRF 공격에 대해서 설명해주세요.

표자 2025. 6. 24. 09:53

CSRF가 뭔가요? 🤔

CSRF(Cross-Site Request Forgery)는 한마디로 "신분도용 사기"와 비슷해요!

일상 예시로 설명하면: 여러분이 은행 앱에 로그인한 상태에서, 악성 사이트를 방문했더니 여러분 모르게 계좌이체가 실행되는 것과 같습니다 💸

브라우저가 "아, 이 사람이 은행 앱에 로그인되어 있으니 진짜 본인이 요청한 거겠구나!"라고 착각하는 거죠 🏦

공격 시나리오 단계별 분석 🎭

1단계: 평범한 로그인 😊

  • 철수가 "매일메일" 서비스에 로그인
  • 서버가 세션 쿠키를 브라우저에 저장
  • 이제 철수는 인증된 사용자!

2단계: 함정에 빠지다 😱

  • 철수가 "무료 아이폰 당첨!" 같은 피싱 사이트 클릭
  • 또는 SNS에서 악성 링크를 클릭
  • 심지어 정상 사이트의 악성 광고를 볼 수도 있어요

3단계: 몰래 공격 실행 🕵️

  • 악성 사이트에 숨겨진 코드가 자동 실행
  • 철수 몰래 "매일메일"로 비밀번호 변경 요청 전송
  • 브라우저가 자동으로 인증 쿠키까지 함께 보냄

4단계: 피해 발생 💥

  • 서버: "아, 철수가 비밀번호 바꾸려고 하는구나!"
  • 철수는 전혀 모르는 사이에 계정 탈취당함

실제 공격 방법들 🎯

1. 이미지 태그 공격 📸

<!-- 사용자가 이 이미지를 로드하는 순간 공격 실행 -->
<img src="https://bank.com/transfer?to=공격자계좌&amount=1000000" style="display:none">

2. 자동 제출 폼 공격 📝

  • 페이지 로드와 동시에 JavaScript로 폼이 자동 제출
  • 사용자는 아무것도 클릭하지 않았는데 요청이 전송됨

3. 링크 클릭 유도 🔗

  • "축하합니다! 상품에 당첨되셨습니다" 같은 사회공학적 기법 활용
  • 클릭하면 악성 요청이 실행되는 링크

 

CSRF 방어 전략 🛡️

1. CSRF 토큰 (가장 효과적!) ⭐

일상 예시: 은행에서 거래할 때 일회용 보안카드 번호를 요구하는 것과 같아요!

  • 서버가 페이지마다 고유한 비밀번호 발급
  • 진짜 사용자만 이 비밀번호를 알 수 있음
  • 요청할 때 이 비밀번호도 함께 보내야 함

2. SameSite 쿠키 🍪

일상 예시: "우리 가게 쿠폰은 우리 가게에서만 사용 가능"과 같은 규칙!

  • SameSite=Strict: 다른 사이트에서는 쿠키 전송 금지
  • SameSite=Lax: GET 요청에만 허용 (더 유연함)

3. Referer 헤더 검증 🔍

일상 예시: "어디서 오셨나요?" 신원 확인과 같아요!

  • 요청이 어느 사이트에서 왔는지 확인
  • 다른 사이트에서 온 요청은 차단
  • 단점: 헤더 조작 가능성 있음

4. 더블 쿠키 검증 🔄

  • 쿠키와 헤더에 같은 토큰을 담아서 전송
  • 두 값이 일치하는지 확인

 

추가로 알아두면 좋은 정보 💡

CSRF vs XSS 차이점 🆚

  • CSRF: 다른 사이트에서 인증된 요청 위조
  • XSS: 같은 사이트에서 악성 스크립트 실행

최신 브라우저의 보안 강화 🔒

  • Chrome 80+부터 SameSite 쿠키 기본값이 Lax로 변경
  • 자동으로 CSRF 공격을 어느 정도 차단

REST API와 CSRF 🔄

  • Stateless API: 세션 쿠키 대신 JWT 토큰 사용 시 CSRF 위험 감소
  • 하지만: 토큰을 localStorage에 저장하면 XSS 공격에 취약해짐

개발자가 놓치기 쉬운 포인트 ⚠️

1. AJAX 요청도 보호해야 해요!

  • 일반 폼뿐만 아니라 fetch/axios 요청도 토큰 필요

2. 파일 업로드도 위험해요!

  • multipart/form-data 요청에도 CSRF 토큰 포함

3. 모든 상태 변경 요청을 보호하세요!

  • POST, PUT, DELETE 등 데이터를 변경하는 모든 요청

실무 팁 🛠️

1. 프레임워크 기본 기능 활용

  • Django: {% csrf_token %} 자동 생성
  • Express: csurf 미들웨어 사용
  • Spring: @EnableWebSecurity 설정

2. 개발 단계에서부터 고려

  • 설계 단계에서 CSRF 방어 계획 수립
  • 코드 리뷰 시 CSRF 방어 여부 체크

면접 답변 💼

CSRF는 사용자가 인증된 상태에서 공격자가 만든 악성 사이트를 통해 의도하지 않은 요청이 전송되는 공격입니다. 브라우저가 자동으로 쿠키를 포함하여 요청을 보내기 때문에 서버는 정당한 요청으로 인식하게 됩니다. 주요 방어 방법으로는 CSRF 토큰 검증, SameSite 쿠키 설정, Referer 헤더 검증 등이 있으며, 특히 CSRF 토큰을 통한 방어가 가장 효과적입니다.

 


 

CSRF 공격에 대해서 설명해주세요.

백엔드와 관련된 질문이에요.

사이트 간 요청 위조(Cross-site Request Forgery, CSRF) 공격은 사용자가 자신의 의지와 상관없이 공격자가 의도한 행위를 특정 웹사이트에 요청하도록 하는 것을 의미합니다.

예를 들어, 특정 사용자가 매일메일 서비스에서 로그인을 수행하고 서버는 해당 사용자에 대한 세션 ID를 Set-Cookie 헤더에 담아서 응답합니다. 그리고, 클라이언트는 쿠키를 저장하고 요청마다 자동으로 전달합니다.

이러한 사용자를 대상으로 공격자는 악성 스크립트가 담긴 페이지에 접속하도록 유도합니다. 유도하는 방법은 다양한데요. 악성 스크립트가 포함된 메일이나 게시글을 작성하거나, 악성 스크립트가 포함된 공격자 사이트 접속 링크를 전달하는 것이 대표적입니다.

사용자가 악성 스크립트가 포함된 페이지에 접속하게 되면 악성 스크립트가 실행됩니다. 이 스크립트는 사용자의 의도와 상관없는 특정한 요청(결제, 비밀번호 변경)을 공격 대상 서버로 보내도록 구현되어 있습니다. 해당 요청은 브라우저에 의해서 자동으로 쿠키에 저장된 세션 ID가 함께 전달됩니다.

예를 들어, 공격자가 만든 사이트 내부에는 다음과 같은 태그가 존재할 수 있습니다.

<img src ="https://maeil-mail.com/member/changePassword?newValue=1234" />

공격자 사이트에 방문한 사용자는 자신의 의지와 무관하게 img 태그로 인해 세션 ID가 포함된 쿠키와 함께 비밀번호 변경 요청을 매일메일 서버로 전달합니다.

CSRF 공격은 어떻게 방어할 수 있나요? 🤓

교차 출처인 상황에서의 요청을 막는 방식으로 CSRF를 방어할 수 있습니다.

첫 번째로, HTTP 헤더 중에 하나인 Referer 요청 헤더를 사용하는 방법이 있습니다. Referer 요청 헤더로 현재 요청을 보낸 페이지의 주소를 알 수 있는데요. 해당 주소와 Host(서버의 도메인 이름) 헤더를 비교하여 다른 경우, 예외를 발생시킬 수 있습니다. 하지만, Referer 요청 헤더는 조작될 수 있다는 점에서 한계가 있습니다.

두 번째로, 템플릿 엔진 기술을(JSP, 타임리프, Pug, Ejs 등) 사용하고 있는 경우라면 CSRF 토큰 방법을 사용해 볼 수 있습니다. 페이지를 생성하기 이전에 사용자 세션에 임의의 CSRF 토큰을 저장합니다. 그리고, 특정 API 요청에 대한 제출 폼을 생성할 때 해당 CSRF 토큰값이 설정된 input 태그를 추가합니다.

<input type = "hidden" name = "csrf_token" value = "csrf_token_12341234" />

실제로 요청이 전달될 때, 해당 input 태그의 CSRF 토큰과 사용자 세션 내부에 존재하는 CSRF 토큰의 일치 여부를 판단하여, CSRF 공격에 대해 방어할 수 있습니다.

이외에도 SameSite 쿠키를 사용하여 크로스 사이트에 대한 쿠키 전송을 제어하거나, 브라우저의 SOP(Same Origin Policy) 정책을 사용하고, CORS 설정으로 교차 출처 접근을 일부분 허용하는 방식으로도 CSRF 공격을 방어할 수 있습니다.

728x90