CSRF 토큰이란?
- CSRF 취약점을 방지하기 위해 서버측 애플리케이션에서 생성하는 난수
-토큰은 클라이언트가 만든 subsequent HTTP request에서 서버측 애플리케이션에 의해 만들어지고 제출
-request가 만들어지고나서 서버측 애플리케이션은 유저 세션과 요청 세션에서 만들어진 두 토큰을 비교
-토큰이 없어지거나 사용자 세션 값과 맞지 않는다면, request는 거절, 사용자 세션 종료, 이벤트가 CSFR로 로그에 남음
CSFR 토큰 생성 방법
-일반적으로 세션 토큰과 같이 CSRF 토큰은 상당한 엔트로피와 예측할 수 없음을 포함
-pseudo-random number generator(PRNG) 암호화 강도를 사용해 CSFR 토큰을 만들 수 있다.
**PRNG: 난수가 발생될 때 타임스탬프와 정적 암호를 기반으로 함
- >악의적인 사용자가 본인에게 발행된 샘플을 기반으로 토큰을 분석할 때 추가적인 장애물이 될 수 있음을 나타냄
=>따라서 다음과 같은 토큰을 생성 및 검증할 때 원칙이 있음
-충분한 엔트로피를 가진 잘 만들어진 난수 생성기를 사용할 것
-토큰 재사용 하지 말기. 사용 가능 주기를 짧게 해야함
-수신된 토큰이 해시를 비교하는 것과 같은 안전한 방법으로 설정된 토큰과 동일한지 확인할 것
-HTTP GET 요청으로 CSRF 토큰을 보내지 말 것. 안그러면 공격자가 url을 직접적으로 이용하고 다른 참조 정보가 있는 헤더가 유출됨
*PHP를 이용한 토큰 생성과정
1. 토큰 생성
1
|
$_SESSION[‘token’] = bin2hex(random_bytes(24));
|
cs |
2. 토큰 검증
1
2
3
4
5
|
if (hash_equals($_SESSION[‘token’], $_POST[‘token’])) {
// Action if the token is valid
} else {
// Action if the token is invalid
}
|
cs |
-토큰을 만들 때 더 보안적으로 접근하려면 각 form마다 다른 토큰을 생성,
-사용자 브라우저에 직접적으로 토큰 노출시키지 말것
-form의 파일 이름을 사용해 토큰을 해시값 검증 할 것
++파일 이름 이용해 토큰의 해시값 검증
1
|
hash_hmac(‘sha256’, ‘post.php’, $_SESSION[‘internal_token’])
|
cs |
CSRF 토큰 전송 방법
-CSRF 토큰은 생명주기 내에서 안전하고 비밀로 취급되어야 함
-POST 방식을 이용해 클라이언트에게 전달
[예시]
-CSFR 토큰이 포함된 필드를 HTML 파일 내 최대한 앞쪽에 배치
-토큰이 포함된 필드를 감춰지지 않는 필드 앞과 사용자가 제어할 수 있는 데이터가 포함된 모드 위치 앞에 배치한다.
->공격자가 조작된 데이터로 HTML 문서를 조작하고 일부를 챕쳐할 수 있는 다양한 기술에 대한 위험을 줄일 수 있다
1
2
3
4
|
<form action="/transfer.do" method="post">
<input type="hidden" name="CSRFToken" value="OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWEwYzU1YWQwMTVhM2JmNGYxYjJiMGI4MjJjZDE1ZDZMGYwMGEwOA==">
[...]
</form>
|
cs |
-CSRF 토큰을 URL 쿼리 문자열에 넣을 수 있지만 안전한 방법은 아님
1. 다양한 포지선에서 로그인 될 수 있음(클라이언트, 서버측 모두)
2. HTTP 참조 헤더가 포함된 채 제 3자에게 전송될 수 있음
3. 사용자 브라우저에 보여질 수 있음
-다른 사용자의 토큰을 예측하거나 캡처하는 공격자를 막기위한 추가적 방법
->javascript를 통해 CSRF 토큰을 사용자 지정 HTTP 요청 헤더에 삽입 (AJAX나 API 엔드포인트에 적합)
-브라우저는 보통 크로스 도메인(서로 다른 도메인 간의 호출)으로 전달된 커스텀 헤더를 허용하지 않음
-단점: XHR을 이용한 CSRF-protected 요청을 만드는 애플리케이션에서 적용 가능/더 많은 복잡한 상황을 고려해야 함
*XHR: AJAX 요청을 생성하는 JavaScript API
**쿠키로 토큰 전송하지 말것
원본
https://www.neuralegion.com/blog/csrf-token/