SameSite
SameSite는 최신 방식의 CSRF 공격 방어 방법 중 하나로서 서버가 쿠키를 설정할 때 SameSite 속성을 지정하여
크로스 사이트 간 쿠키 전송에 대한 제어를 핸들링 할 수 있다
Spring Security는 세션 쿠키의 생성을 직접 제어하지 않기 때문에 SameSite 속성에 대한 지원을 제공하지 않지만
Spring Session 은 SameSite 속성을 지원한다
크로스 사이트(Cross-site)란 웹 애플리케이션에서 서로 다른 출처(도메인) 간의 상호작용을 설명하는 개념입니다. 이 용어는 주로 웹 보안과 관련이 있으며, 가장 일반적으로 크로스 사이트 스크립팅(Cross-Site Scripting, XSS)과 크로스 사이트 요청 위조(Cross-Site Request Forgery, CSRF)와 같은 공격을 지칭합니다.
- 크로스 사이트 스크립팅(XSS): 악의적인 사용자가 신뢰할 수 있는 웹사이트에 스크립트를 삽입하여 다른 사용자의 브라우저에서 실행하게 하는 공격입니다. 이를 통해 사용자의 쿠키, 세션 정보 등을 탈취할 수 있습니다.
- 크로스 사이트 요청 위조(CSRF): 사용자가 인증된 세션을 가진 웹사이트에서 다른 사이트에 요청을 보내도록 유도하는 공격입니다. 이를 통해 공격자는 사용자의 권한으로 악의적인 작업을 수행할 수 있습니다.
Samesite 속성
Strict
동일 사이트에서 오는 모든 요청에 쿠키가 포함되고 크로스 사이트간 HTTP 요청에 쿠키가 포함되지 않는다
Lax(기본 설정)
동일 사이트에서 오거나 Top Level Navigation 에서 오는 요청 및 메소드가 읽기 전용인 경우 쿠키가 전송되고
그렇지 않으면 HTTP 요청에 쿠키가 포함되지 않는다
사용자가 링크(<a>)를 클릭하거나 window.location.replace , 302 리다이렉트 등의 이동이 포함된다. -> 쿠키 전송
그러나 <iframe>이나 <img>를 문서에 삽입, AJAX 통신 등은 쿠키가 전송되지 않는다
- 쿠키가 전송되는 경우:
- 동일 사이트 요청: 사용자가 같은 사이트 내에서 이동하는 경우에는 쿠키가 정상적으로 전송됩니다. 예를 들어, 사용자가 같은 도메인 내의 다른 페이지로 이동하는 경우입니다.
- Top Level Navigation: 사용자가 링크(<a>)를 클릭하거나 window.location.replace()와 같은 방법으로 페이지를 이동하는 경우, 그리고 302 리다이렉트가 발생하는 경우에도 쿠키가 전송됩니다.
- 쿠키가 전송되지 않는 경우:
- 임베디드 콘텐츠: <iframe>, <img> 태그를 사용하여 다른 도메인의 콘텐츠를 삽입할 때, 해당 요청에 대해서는 쿠키가 전송되지 않습니다.
- AJAX 통신: AJAX를 통해 다른 도메인에 요청을 보내는 경우에도 쿠키가 전송되지 않습니다.
요약
- 전송되는 상황: 사용자가 클릭하여 새로운 페이지로 이동하는 경우(동일 사이트) 및 직접적인 페이지 이동이 발생하는 경우.
- 전송되지 않는 상황: 다른 사이트의 리소스를 임베드하거나 AJAX 요청을 통해 데이터를 가져오는 경우.
이러한 설정은 사용자가 의도하지 않은 방식으로 쿠키가 전송되는 것을 방지하여 보안을 강화하는 역할을 합니다. SameSite 속성은 웹 애플리케이션의 보안을 강화하고 CSRF 공격으로부터 보호하는 데 중요한 역할을 합니다.
"리소스를 임베드한다"는 것은 웹 페이지에 외부 콘텐츠나 리소스를 포함시키는 것을 의미합니다. 이러한 리소스는 다른 웹사이트나 도메인에서 제공하는 이미지, 비디오, 오디오, HTML 문서, 또는 애플리케이션 등을 포함할 수 있습니다.
임베딩의 예시
- 소셜 미디어 게시물: 트위터, 페이스북 등의 소셜 미디어 플랫폼에서 특정 게시물을 웹 페이지에 임베드할 수 있습니다. 예를 들어, 트위터의 트윗을 웹사이트에 표시하는 경우입니다.
- 비디오: 유튜브 비디오를 웹 페이지에 삽입하여 사용자가 페이지에서 직접 비디오를 시청할 수 있도록 할 수 있습니다.
- 지도: 구글 맵의 특정 위치를 웹 페이지에 임베드하여 방문자에게 해당 위치를 쉽게 보여줄 수 있습니다
None
동일 사이트 및 크로스 사이트 요청의 경우에도 쿠키가 전송된다. 이 모드에서는 HTTS 의한 Secure 쿠키로 설정되야 한다
Secure 쿠키란?
- Secure 속성: 쿠키에 Secure 속성이 설정되면, 이 쿠키는 오직 HTTPS(SSL/TLS)를 통해 암호화된 연결을 사용할 때만 전송됩니다. 즉, HTTP 프로토콜을 사용하는 경우에는 전송되지 않습니다.
- 목적: Secure 속성은 쿠키가 안전하게 전송되도록 하여, 네트워크에서 쿠키가 도청당하는 것을 방지합니다. HTTPS는 데이터를 암호화하여 전송하므로, 중간에 누군가가 데이터에 접근하는 것을 어렵게 만듭니다.
SameSite 예시
대부분의 현대 브라우저는 SameSite 속성을 지원하지만, 여전히 사용 중인 오래된 브라우저는 지원하지 않을 수 있다
SameSite 를 CSRF 공격에 대한 유일한 방어 수단으로서가 아니라 심층적으로 강화된 방어의 일환으로 사용하는 것을
권장하고 있다
Spring Session 으로 SameSite 적용하기
implementation 'org.springframework.session:spring-session-core'
@Configuration // Spring의 설정 클래스를 나타냅니다.
@EnableSpringHttpSession // Spring의 HttpSession을 활성화합니다.
public class HttpSessionConfig {
@Bean // 이 메서드가 Spring의 Bean으로 등록됨을 나타냅니다.
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer(); // 기본 쿠키 직렬화기 생성
serializer.setUseSecureCookie(true); // HTTPS를 사용할 때만 쿠키가 전송되도록 설정
serializer.setUseHttpOnlyCookie(true); // JavaScript에서 쿠키에 접근할 수 없도록 설정
serializer.setSameSite("Lax"); // SameSite 속성의 기본값은 Lax이다. 이 설정안해도 됨
return serializer; // 설정된 쿠키 직렬화기를 반환
}
@Bean // 이 메서드가 Spring의 Bean으로 등록됨을 나타냅니다.
public SessionRepository<MapSession> sessionRepository() {
// ConcurrentHashMap을 사용하여 세션을 저장하는 MapSessionRepository 생성
return new MapSessionRepository(new ConcurrentHashMap<>());
}
}
JSESSIONID는 WAS가 세션을 발급할때의 키 이름이고
@EnableSpringHttpSession을 추가해서 Spring Session이 세션을 만들때는 Session이라는 이름의 키를 가진다.
JSESSIONID는 기본적으로 웹 애플리케이션 서버(WAS, Web Application Server)가 세션을 식별할 때 사용하는 쿠키의 이름입니다. 그러나 @EnableSpringHttpSession을 사용하여 Spring Session을 활성화하면, Spring Session이 자체적으로 세션을 관리하게 되며, 이때 쿠키의 이름이 Session으로 변경됩니다
sessionRepository() 메서드
- 이 메서드는 세션 저장소를 정의하는 메서드입니다. 여기서는 MapSessionRepository를 사용하여 세션 데이터를 메모리에 저장하도록 설정합니다.
- MapSessionRepository는 애플리케이션 내부의 ConcurrentHashMap에 세션을 저장하는 간단한 구현체로, 별도의 외부 저장소가 필요 없는 상황이나 테스트 환경에서 유용하게 사용할 수 있습니다.
- ConcurrentHashMap을 사용하여 스레드 안전성을 보장하고, 여러 요청이 동시에 세션에 접근할 때 충돌이 발생하지 않도록 합니다.
- 하지만 이 설정은 애플리케이션을 재시작하면 세션 데이터가 사라지므로, 실제 운영 환경에서는 Redis, 데이터베이스와 같은 외부 세션 저장소를 사용하는 것이 일반적입니다.
sessionRepository 메서드는 주로 테스트나 강의용 코드에서 간단하게 세션 저장을 구현하기 위해 사용되는 설정입니다. 이 코드에서는 MapSessionRepository를 사용하여 애플리케이션의 메모리에 세션을 저장하도록 하고 있기 때문에, 애플리케이션이 재시작되면 세션 데이터가 모두 삭제됩니다.
실제 운영 환경에서는 Redis, JDBC, 또는 MongoDB와 같은 외부 저장소를 세션 저장소로 설정하는 것이 일반적입니다. 외부 저장소를 사용하면 애플리케이션 서버가 여러 대일 때도 중앙 집중식으로 세션을 관리할 수 있어, 서버 간 로드 밸런싱과 장애 조치에 유리합니다.
따라서 sessionRepository 메서드에서 MapSessionRepository를 사용하는 것은 간단히 세션 저장을 테스트하거나, Spring Session의 동작을 이해하기 위해서 강의나 개발 중에 사용되는 코드로 볼 수 있습니다.
'인프런 > 스프링 시큐리티 완전 정복 [6.x 개정판]' 카테고리의 다른 글
19) 인가 프로세스 - 요청 기반 권한 부여HttpSecurity.authorizeHttpRequests() (0) | 2024.11.01 |
---|---|
17) 악용보호 - CSRF(Cross Site Request Forgery, 사이트 간 요청 위조) (1) | 2024.10.28 |
16) 악용보호 - CORS (1) | 2024.10.25 |
15) 예외처리 - exceptionHandling(), ExceptionTranslationFilter (0) | 2024.10.24 |
14) 세션관리 - SessionManagementFilter / ConcurrentSessionFilter (1) | 2024.10.23 |
댓글