CSRF
CSRF에 대하여
CSRF
CSRF(Cross-Site Request Forgery) 사이트 간 요청 위조
- 공격자가 사용자의 브라우저를 악용하여 사용자의 의도와 상관없이 특정 웹 애플리케이션에 요청을 보내도록 하는 공격기법
- 예) 사용자가 정상적으로 로그인해 있는 상태애서 공격자가 의도한 악의적인 요청을 전송해, 사용자 계정으로 특정 동작(게시글 작성, 비밀번호 변경, 결제 등)을 수행하게 만들 수 있다.
기본개념
- 사용자 인증 유지: 사용자가 웹사이트 A에 로그인하면 서버는 세션 쿠키나 토큰 등으로 인증 상태를 식별
- 공격자의 의도된 페이지 접근: 사용자에게 악성 승크립트가 담긴 페이지 혹은 링크(예: 이메일, 게시글 등)를 클릭하거나, 공격자가 심어 놓은 HTML폼이 자동으로 전송되면, 사용자가 의도치 않아도 특정 요청이 사용자 브라우저에서 실행 된다.
- 서버는 정상적으로 간주함: 요청이 전달될 때, 사용자가 이미 로그인한 상태이기 때문에 서버는 인증 정보를 포함한 요청(쿠키, 세션 등)을 정상적인 요청으로 처리하게 된다.
2. CSRF 공격 예시
- 포럼에 글 작성
- 사용자는 A 사이트에 로그인해 있음.
- 공격자는 포럼(또는 메일, 다른 웹페이지)에
img
태그나form
태그 등을 삽입하여, 해당 페이지에 접속할 때 A 사이트에 특정 요청을 보내도록 한다. - 사용자는 별다른 의심 없이 포럼 페이지를 열었고, A 사이트에는 사용자가 ‘글 작성’ 요청을 한 것처럼 서버에 전달
- 서버는 이미 로그인이 된 상태를 확인하고, 해당 요청을 정상적으로 처리
- 계정 설정 변경
- 사용자가 B 사이트에 로그인해 비밀번호를 유지하고 있는 상태
- 공격자가 이메일이나 메신저를 통해 “이벤트 당첨 확인” 등의 링크를 보내, 사용자가 클릭하도록 유도
- 클릭 시 자동으로 ‘비밀번호 변경’ 또는 ‘관리자 권한 변경’ 등의 요청이 B 사이트에 전송될 수 있음
- 서버 입장에서는 사용자 세션이 유효하므로, 해당 요청을 합법적인 요청으로 인식해 적용
3. CSRF 방어 기법
3.1 CSRF 토큰(CSRF Token) 사용
- 이중 양식 제출(토큰 검증)
- 각 HTML 폼 혹은 요청마다 난수 기반의 토큰을 생성하여, 이를 숨김 필드나 헤더에 포함해 전송
- 서버는 요청 시 전달된 토큰 값이 세션에 저장된 토큰과 일치하는지 비교하여 검증
- 일치하지 않는다면 요청을 거부
- 예시) Spring Security, Django, Ruby on Rails 등 대부분의 웹 프레임워크는 CSRF 토큰 기능을 제공한다.
- Double Submit Cookie 패턴
- 서버는 난수 기반의 CSRF 토큰을 쿠키와 함께 전송
- 클라이언트는 해당 토큰을 쿠키에서 읽어서 폼 전송 시 추가 헤더나 숨김 필드에 함께 담는다.
- 서버는 쿠키로 전달받은 토큰과 폼(혹은 헤더)으로 전달된 토큰을 비교하여 검증
3.2 Referer 및 Origin 헤더 검증
- Referer 혹은 Origin 헤더 확인
- 요청에 포함되는
Referer
혹은Origin
값을 확인하여, 해당 도메인이 정상적인 출처(whitelist)인지 확인 - 단, 일부 환경(프록시, 브라우저 옵션 등)에서 Referer 값이 제거되거나 변조될 수 있기 때문에, 보조적인 수단으로 사용되는 경우가 많다.
- HTTPS에서만 상대적으로 안전하게 사용하는 방법이나, CSRF 토큰 검증보다 보안성이 낮다.
- 요청에 포함되는
3.3 SameSite 쿠키 속성
- SameSite 속성
- 쿠키에
SameSite=Lax
또는SameSite=Strict
속성을 설정해, 외부 사이트에서 임의로 전송될 수 없도록 제한 - Chromium 기반 브라우저(Chrome, Edge 등)는 보안 강화를 위해 기본값을
SameSite=Lax
로 설정하는 추세 - 다만, 이 설정만으로 모든 CSRF 공격을 완벽히 차단할 수 있는 것은 아니므로, CSRF 토큰과 함께 사용하는 것이 안전하다.
- 쿠키에
3.4 사용자 교육 및 기타 보안 대책
- 의심스러운 링크 클릭 자제
- 쿠키 유효기간 최소화, 세션 강제 만료
- 사용자가 민감한 작업(예: 결제, 계정 설정) 등을 완료한 뒤에는 자동 로그아웃 혹은 세션 만료를 하도록 주의해야 한다.
따라서 CSRF 공격 방어를 위해서는 1) 사용자 요청에 고유한 CSRF 토큰을 부여하고,
2) 서버 측에서 이 토큰을 철저히 검증하며,
3) 세션·쿠키 등 인증 관련 설정을 보안적으로 꼼꼼히 구성하고,
4) 사용자에게 의심스러운 링크 클릭 자제를 습관화하도록 교육하는 전방위적 접근이 중요
This post is licensed under CC BY 4.0 by the author.