티스토리 뷰

쿠키 보안 표준

 

Thirdparty cookie를 처리하면서 발생한 문제.

 

BE 도메인 : api.[메인 도메인 주소].com
FE 도메인 : web.[메인 도메인 주소].com

 

도메인 주소의 전체 이름은 다르지만 하위 도메인 주소를 뺀 부분이 같다.

 

떄문에 별 생각 없이 쿠키의 도메인을 [메인 도메인 주소].com으로 지정해줬다.

 

이럴 경우 web.[메인 도메인 주소].com에서 해당 쿠키를 확인할 수 없다. 

 

하위 도메인에서 쿠키를 확인할 수 있도록 해야하기 때문에,

 

"."을 반드시 포함시켜서 .[메인 도메인 주소].com 으로 지정해줘야 한다.

 

작업할 당시에는 쿠키에 별 생각 없이 아래와 같이 도메인을 붙였다.

public Cookie setCookie(String guestId) {
    int maxAge = 24 * 60 * 60 ;
    Cookie guestCookie = new Cookie("guest_id", guestId);
    guestCookie.setMaxAge(maxAge);
    guestCookie.domain(".hello.com")
    guestCookie.setPath("/");
    return guestCookie;
}

그런데... 아래와 같은 에러가 발생했다.

java.lang.IllegalArgumentException: An invalid domain [.hello.com] was specified for this cookie
	at org.apache.tomcat.util.http.Rfc6265CookieProcessor.validateDomain(Rfc6265CookieProcessor.java:244)
	at org.apache.tomcat.util.http.Rfc6265CookieProcessor.generateHeader(Rfc6265CookieProcessor.java:150)
	at org.apache.catalina.connector.Response.generateCookieString(Response.java:944)
	at org.apache.catalina.connector.Response.addCookie(Response.java:900)
	at org.apache.catalina.connector.ResponseFacade.addCookie(ResponseFacade.java:313)


// 아래와 같은 에러가 발생하는 경우도 있다고 한다.
java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value

(hello.com 은 가칭입니다) 도메인의 이름은 가칭이지만 dev 테스트에선 정확히 맞춰서 작성했지만 에러가 발생했다.

 

이게 별 이유는 아니고 도메인에 "." 이 포함되서 그렇다.

 

java servlet에서는 쿠키의 보안을 위해서, 범용적인 사용을 막기 위해 하위 도메인에서 사용하지 못하도록 차단해버렸다.

 

그리고, Spring Boot에서 사용되는 내장형 Tomcat은 도메인에 "."을 시작하는 쿠키 형식(version 0)을 제공하지 않는다.

 

이 문제를 해결하기 위해서는 두 가지 방법이 있다.

 

1. javax에서 제공하는 기본 쿠키를 사용할 경우 LegacyCookieProcessor를 설정한다.

https://docs.spring.io/spring-boot/docs/2.0.6.RELEASE/reference/html/howto-embedded-web-servers.html#howto-use-tomcat-legacycookieprocessor

@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
    return (factory) -> factory
            .addContextCustomizers((context) -> context.setCookieProcessor(new LegacyCookieProcessor()));
}

LegacyCookieProcessor 객체를 쓰는 빈을 하나 띄워주면 해결된다.

 

2. ResponseCookie를 사용한다.

스프링부트는 모든 쿠키 표준을 지원하는 쿠키를 만들어줬다.

public String setGuestCookie(String guestId) {
    int maxAge = 10 * 365 * 24 * 60 * 60 ; // 10년으로 설정

    return ResponseCookie.from("guest_id", guestId)
                         .domain(".hello.com")
                         .maxAge(maxAge)
                         .sameSite("None")
                         .path("/")
                         .build().toString();
}

 

둘 중 하나를 선택해서 사용하면 된다. 

 

마치며

하위도메인에서 쿠키를 차단할 정도로 쿠키에 많은 정보를 담고 있나가 문제인 것 같다.

 

쿠키의 보안이 얼마나 중요한가? 는 아직까지 잘 느끼지 못하겠다.

 

사실 Thirdparty cookie가 정말 보안적인 이슈가 있는 것인가? 도 잘 와닿지 않는다.

 

웹서비스에서 구르다보면 더 느낄 수 있지 않을까?

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함