CSRF (Cross-Stie Request Forgery)
WEB - 사이트 간 요청 위조
공격 목적 & 과정
CSRF(사이트 간 요청 위조)란 공격자가 사용자로 하여금 특정 웹 애플리케이션을 몰래 실행하는 방식이다. 이 공격은 사용자가 해당 웹 애플리케이션에 이미 로그인한 상태에서 이루어진다.
공격이 진행되는 과정은 아래와 같다.
- 공격자는 이메일 또는 문자 등을 이용하여 사용자를 자신이 만든 웹 페이지를 방문하게 만든다.
-
해당 페이지에는 다음과 같은 HTML에 삽입되어 있다.
<img src="http://bank.com/transfer?to=Mallory&amount=1000" width="0" height="0">
- 브라우저가 이미지를 로드하려고 시도하는 과정에서 은행 웹 애플리케이션으로 요청이 전송된다.
- 은행에 로그인 한 상태였다면 인증에 성공하고 공격자가 원하는 요청(돈이 송금됨)이 발생한다.
예방
CSRF 공격이 가능한 이유는 사용자가 이용중인 웹사이트에서 전송되는 (정상적)요청과 공격자의 웹사이트에서 전송되는 (악의적)요청이 동일하기 때문이다. 공격을 막기 위해서는 악성 사이트는 제공할 수 없는 무언가가 정상 요청에 있어서 그 둘을 구별할 수 있어야 한다.
Spring은 CSRF 공격을 막는 두 가지 매커니즘을 제공한다.
Synchronizer token pattern
CSRF를 막기 위해 가장 널리 쓰이는 방법이다. 이 방식에서 각 HTTP request는 secure random generated value와 session cookie(session id)를 함께 제출하도록 요구된다. 이 값을 CSRF 토큰이라고 한다.
이 방법의 핵심은 CSRF 토큰이 브라우저에 의해 자동적으로 추가되지 않는 HTTP 요청의 일부여야 한다는 것이다. 즉 CSRF 토큰은 쿠키가 아닌 요청의 헤더 또는 http parameter 등에 포함되어 전송되어야 한다.
모든 요청에 대해 CSRF 토큰을 요구하지 않고 애플리케이션의 상태를 변경하는 요청에 대해서만 CSRF 토큰을 요청할 수 있다. 그러기 위해서는 safe HTTP method들의 indempotent(멱등성)를 보장해야 한다. 이러한 방식은 웹사이트의 접근성(usability)를 향상시킨다. 외부 사이트들로부터의 연결을 허용하기 때문이다.
<form method="post"
action="/transfer">
<input type="hidden"
name="_csrf"
value="4bfd1575-3ad1-4d21-96c7-4ef2d9f86721"/> <!-- secure random value -->
<input type="text"
name="amount"/>
<input type="text"
name="routingNumber"/>
<input type="hidden"
name="account"/>
<input type="submit"
value="Transfer"/>
</form>
CSRF 토큰은 _csrf
라는 HTTP parameter에 값으로서 서버에 전송된다. 이 방식은 JSP 등을 사용하는 SSR 방식의 웹 애플리케이션에서 사용된다.
CSRF 토큰은 해당 페이지에 접속할 때마다 서버에서 생성한 값이기 때문에 악성 사이트에는 존재하지 않는다.
CSRF 토큰을 활용하여 CSRF를 막는 매커니즘은 다음과 같다.
- 토큰 생성 - 사용자가 특정 페이지(로그인 페이지 등)에 접속할 때마다 서버는 CSRF 토큰을 생성한다.
- 세션 저장 - 생성된 토큰은 세션 정보와 함께 세션 서버에 저장된다. (아직 인증이 완료되지 않은 단계에서도 임시 세션이 생성된다.)
- 페이지 응답 - 생성된 토큰을 HTML 응답에 포함하여 클라이언트에게 전송한다.
- 요청 검증 - 사용자가 해당 폼을 제출하면, 폼 속의 CSRF 토큰을 사용자의 세션 정보와 비교하여 유효성을 검증한다.
Safe methods란 조회만 수행하는(read-only) 요청이다.
SameSite Attritubte
새롭게 떠오르고 잇는 CSRF 공격 예방법이다. 쿠키에 SameSite Attribute를 명시하는 방법이다. SameSite 속성은 웹 브라우저의 쿠키에 대한 설정으로, 다른 사이트로부터의 요청에 해당 쿠키가 포함되지 않도록 명시한다.
Comments