- CSRF (Cross-Site Request Forgery)란?
CSRF는 웹 애플리케이션의 보안 취약점 중 하나로, 공격자가 사용자의 권한을 도용하여 사용자가 의도하지 않은 요청을 웹 애플리케이션에 보내는 공격을 의미한다. 공격자는 희생자가 이미 로그인한 상태에서 악의적인 요청을 실행하게 하여, 희생자의 계정으로 원치 않는 작업을 수행하도록 유도한다. 예를 들어, 희생자의 계정으로 금액을 이체하거나 계정 정보를 변경하는 등의 악의적인 작업을 수행할 수 있다.
- CSRF 토큰 (CSRF Token)이란?
CSRF 토큰은 웹 애플리케이션의 보안 취약성을 줄이기 위해 사용되는 보안 기술 중 하나이다. 사용자가 요청을 보낼 때마다 해당 요청에 대한 랜덤한 토큰을 함께 제공하고, 서버는 이 토큰을 검증하여 요청이 유효한지 확인한다. 이렇게 함으로써 외부 공격자가 사용자의 토큰을 알지 못하면 해당 요청을 실행할 수 없게 된다.
CSRF 토큰의 동작 방식:
- 사용자가 웹 애플리케이션에 로그인하면 서버는 세션에 CSRF 토큰을 생성하여 저장한다.
- 웹 페이지에 접근할 때마다 페이지에 CSRF 토큰을 포함한 폼을 생성하거나, HTTP 헤더에 CSRF 토큰을 추가한다.
- 사용자가 액션을 취할 때마다 서버로부터 받은 CSRF 토큰을 포함한 요청을 보낸다.
- 서버는 받은 요청의 CSRF 토큰과 세션에 저장된 CSRF 토큰을 비교하여 요청의 유효성을 검증한다.
- CSRF 토큰이 일치하면 요청이 처리되고, 일치하지 않으면 요청은 거부된다.
스프링 시큐리티는 CSRF 방어 기능을 기본적으로 제공하며, 이를 활용하여 CSRF 공격으로부터 보호할 수 있다. CSRF 토큰은 폼 제출 시 또는 AJAX 요청 시 요청 데이터에 포함하여 전달되어야 하며, 서버에서는 이 토큰을 검증하여 요청의 유효성을 확인한다. 이를 통해 사용자의 권한을 무단으로 도용하는 CSRF 공격을 막을 수 있다.
"서버는 받은 요청의 CSRF 토큰과 세션에 저장된 CSRF 토큰을 비교하여 요청의 유효성을 검증한다."
Q. 세션에 저장된 토큰과 요청을 보낼 때마다 랜덤으로 생성한 토큰은 다르지 않나? 어떻게 비교 가능?
A. 요청 토큰의 유효성 검증은 세션 토큰과의 일치 여부가 아니라, 해당 토큰이 서버에서 유효한지를 확인하는 것을 의미한다. 이를 위해 서버는 생성된 요청 토큰을 통해 누가 요청을 보내는지를 확인하고, 해당 요청이 유효한지를 판단한다.
CSRF 방어에서의 토큰은 세션 토큰(CSRF Token),요청 토큰(Request Token) 두 종류로 나뉜다.
- 세션 토큰 (CSRF Token):
- 사용자가 로그인한 후 서버에서 생성되어 세션에 저장되는 토큰.
- 세션 토큰은 사용자를 식별하고 세션의 유효성을 검증하기 위해 사용된다.
- 요청 토큰 (Request Token):
- 사용자의 요청마다 랜덤하게 생성되어 요청과 함께 제출되는 토큰.
- 요청 토큰은 해당 요청이 실제로 사용자의 의도에 따라 발생한 것인지 확인하는 역할을 한다.
- 서버 측 동작:
- 사용자가 로그인하면 세션 토큰이 생성되어 세션에 저장된다.
- 사용자가 요청을 보낼 때마다, 해당 요청에 대한 랜덤한 요청 토큰을 생성하고 이를 요청의 파라미터 또는 헤더에 포함하여 제공한다.
- 서버는 받은 요청 토큰과 세션에 저장된 세션 토큰을 비교하여, 요청의 유효성을 검증한다.
- 세션 토큰과 요청 토큰이 일치하지 않거나, 세션에 저장된 토큰이 없을 경우 서버는 요청을 거부한다.
서버에서는 각 요청마다 세션 토큰과 요청 토큰을 따로 검사하여 두 토큰 모두의 유효성을 확인한다.
요청 토큰의 유효성 검증은 세션 토큰과의 일치 여부가 아니라, 해당 토큰이 서버에서 유효한지를 확인하는 것을 의미한다. 이를 위해 서버는 생성된 요청 토큰을 통해 누가 요청을 보내는지를 확인하고, 해당 요청이 유효한지를 판단한다.
요청 토큰은 서버에서 랜덤하게 생성되어 클라이언트에게 제공되며, 클라이언트는 이를 요청에 포함시켜 서버에 보낸다. 서버는 이 요청 토큰을 검사하여 해당 요청을 보낸 사용자의 신원이 세션과 일치하는지 확인하고, 요청이 유효한지 판단한다. 이를 통해 CSRF 공격과 같은 보안 위협을 방지할 수 있다.
- JWT란?
JWT( JSON Web Token)는 클라이언트와 서버 간의 정보를 안전하게 전달하기 위해 사용되는 토큰 기반의 인증 방식이다. JWT는 JSON 형식으로 구성되어 있으며, 클라이언트가 서버에 대한 신원을 증명하거나 정보를 주고받을 때 사용된다.
JWT는 Header, Payload, Signature 세 부분으로 나뉘어져 있다
- Header:
JWT의 유형과 암호화 알고리즘 정보를 포함한다.
jsonCopy code { "alg": "HS256", "typ": "JWT" } - Payload:
JWT에 담길 정보를 포함한다. 이 부분에는 클라이언트가 서버에 전달하고자 하는 데이터가 포함된다.jsonCopy code { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 } - Signature:
Header와 Payload의 내용을 바탕으로 서버에서 생성되며, 이를 통해 토큰의 무결성과 누구나 토큰을 생성한 것이 아님을 확인할 수 있다.plaintextCopy code HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )
- JWT의 작동 원리
- 사용자가 로그인하면 서버는 해당 사용자에 대한 정보를 포함한 JWT를 생성한다.
- 클라이언트는 이 JWT를 받아서 보관하고, 요청을 보낼 때 마다 이 JWT를 요청 헤더에 포함시켜 서버에 전달한다.
- 서버는 요청을 받을 때마다 JWT의 유효성을 확인하고, JWT의 내용을 해독하여 사용자의 신원을 확인한다.
- 서명 검증을 통해 JWT가 변조되지 않았는지도 확인한다.
- JWT의 장점
- 간단하고 사용하기 쉬움
- 정보를 JSON 형식으로 전달하므로 다양한 데이터를 효과적으로 표현 가능
- 서명을 통한 무결성 검증과 암호화를 통한 보안 강화 가능
- JWT 사용 시 주의점
- JWT를 제대로 관리하지 않으면 정보 노출 및 변조 위험
- 크기가 커질 수 있으며, 모든 정보를 클라이언트에 포함시킬 필요가 없음
- 한 번 발급된 JWT는 만료 전까지 계속 사용 가능하므로 만료 기간을 적절히 설정해야 함
- CSRF 토큰과 JWT의 차이점
CSRF 토큰과 JWT는 둘 다 웹 보안과 관련된 토큰 기술이지만, 목적과 사용 방법, 동작 방식 등에서 차이가 있다.
- 목적:
- CSRF 토큰 (Cross-Site Request Forgery Token): 주로 CSRF 공격을 방어하기 위해 사용된다. 서버가 클라이언트에게 제공하는 토큰으로, 해당 토큰을 요청에 포함시켜 원치 않는 요청으로부터 서버를 보호한다.
- JWT (JSON Web Token): 인증 및 정보 교환을 위해 사용되는 토큰이다. 사용자의 신원을 증명하거나 데이터를 안전하게 전달하기 위해 사용된다.
- 구성:
- CSRF 토큰: CSRF 토큰은 주로 서버에서 생성하며, 클라이언트의 세션에 저장된다.
- JWT: JWT는 Header, Payload, Signature로 구성되며, 서버에서 생성하고 클라이언트에게 전달된다.
- 용도:
- CSRF 토큰: 주로 웹 애플리케이션에서 CSRF 공격을 방어하기 위해 사용된다.
- JWT: 주로 사용자 인증, 권한 부여, 정보 교환에 사용된다.
- 유효성 검증:
- CSRF 토큰: 서버는 요청을 받을 때 요청 헤더나 요청 파라미터에 포함된 CSRF 토큰을 검증하여 요청이 유효한지 확인한다.
- JWT: 서버는 JWT의 서명을 검증하여 토큰의 무결성을 확인하고, 클라이언트의 정보를 추출하여 인증 및 권한을 확인한다.
- 보안성:
- CSRF 토큰: CSRF 토큰은 CSRF 공격을 방어하는 데 사용되며, 서버가 클라이언트에게 토큰을 제공하는 방식이다.
- JWT: JWT는 정보 교환과 인증을 위해 사용되며, 서버가 토큰을 생성하여 클라이언트에게 전달하고 클라이언트는 이를 요청에 포함시켜 사용한다.
- 기간:
- CSRF 토큰: 보통 요청 당시에 생성되고 사용된다.
- JWT: 보통 사용자 인증 등에 사용되며, 만료 기간을 포함하여 설정될 수 있다.
CSRF 토큰과 JWT는 각각 다른 목적과 상황에 맞게 사용되며, 웹 애플리케이션의 보안을 강화하기 위해 사용되는 다양한 기술 중의 하나이다.
'BackEnd > spring' 카테고리의 다른 글
| IntelliJ에서 yml 파일 관리하기: .gitignore와 환경변수 (0) | 2024.05.11 |
|---|---|
| Spring Boot에서 JSP 사용하기 (0) | 2024.05.05 |
| Spring Security란? (0) | 2023.08.09 |
| [Spring Boot] Spring Security를 사용하여 권한 설정하는 방법 (0) | 2023.07.25 |
| [Spring Boot] 의존성 주입 / 객체 생성 방법 - 멤버변수와 생성자, @Configuration과 @Bean (0) | 2023.06.14 |