키패드가 RN 환경에서 복호화가 안됐던 이유
Interview

키패드가 RN 환경에서 복호화가 안됐던 이유

쿠키 SameSite 설정으로 인한 플랫폼 간 비일관적인 복호화 이슈

#RN#Cookie
3
559

이슈

  • 웹 클라이언트 키패드 샘플이 정상적으로 데이터 요청을 하던 동일한 키패드 서버에, RN 웹뷰에서 동일한 요청을 했으나 RN 웹뷰에서만 복호화 이슈가 발생함.
  • 서버에서 동일한 형태의 응답값을 받는 것까지 확인한 상황.

상황 및 이슈 분석

  • 서버에서 로그를 찍어봤을 때, 다른 요청과 응답 모두 정상적으로 오고가는데 복호화에 대해서만 에러 발생
    • 복호화 에러 원인을 파악해 보았을 때, RSA 공개키 발급 시 부여한 세션ID와 복호화 요청을 받았을 때 세션이 일치하지 않아서 발생
  • 기본적으로, 클라이언트로부터 RSA 공개키 요청/복호화 요청을 받을 때 모두, 해당 요청에 동봉된 JSESSIONID 세션 쿠키가 없다면, 세션 쿠키를 생성 후 보냄.
    • 분명 서버에서 세션 ID 값을 받았는데, 복호화 진행 시 세션이 다르다는 건 어디선가 새로 재발급이 이루어졌다는 것이고, 그렇다는 건 서버에서 복호화 요청을 받을 때 RSA 응답에 동봉한 그 쿠키(세션ID)를 받지 못했다는 거고, 그렇다는 것은 클라이언트에서 쿠키를 동봉하지 않았다는 것이라고 유추가 가능함.

삽질

  • 쿠키가 어디서 유실되는 지 당최 왜 동봉이 안되는 건지 확인하기 위해 서버사이드에서 클라이언트사이드에서 요청과 응답을 막 찍어댔는데, 이게 불가능하다는 걸 알면서도 계속했음…
    • HttpOnly 쿠키는 자바스크립트로 접근이 안됨.
    • 헤더의 **Set-Cookie**는 그냥 조회 자체가 안됨 → **null**임.
  • 웹뷰에서 쿠키를 받지를 못했거나, 유실이 된다라고 거의 판단이 이루어짐.
    • 도대체 왜 브라우저는 쿠키를 잘 동봉해서 보내는데, 웹뷰는 동봉을 못하는 것일까?
    • 자바스크립트로 확인이 어렵고, 웹뷰에서 쿠키를 저장하는 공간을 확인하는 방법을 모르니 쿠키를 받긴 받았는지, 받지도 않았는지 확인도 못함

해결

  • 아주 우연히 서버에서 쿠키를 SameSite=None으로 설정하니 바로 해결됐음.
  • SameSite크로스 사이트 요청에 해당 쿠키를 동봉할지 결정하는 속성
    • 기존에는 SameSite가 명시되지 않아 Lax처럼 처리되었고, RN 웹뷰에서 키패드 서버로 직접 보내는 fetch() 요청에는 JSESSIONID가 동봉되지 않았음.
    • SameSite=None으로 설정하자 크로스 사이트 요청에도 JSESSIONID가 다시 동봉되었고, 공개키를 발급한 세션과 복호화 요청의 세션이 동일해져 정상적으로 복호화됨.
    • 현재 브라우저 정책에서는 일반적으로 SameSite=NoneSecure를 함께 설정해야 함.

사후 분석

  • 근데 왜 WebView에서만 이슈가 발생했고, SameSite=None을 설정하지 않은 것이 웹 샘플에서는 문제가 되지 않았는가?
  1. 현대적인 Chromium 계열 환경에서는 쿠키에 SameSite를 명시하지 않으면 기본적으로 SameSite=Lax처럼 처리됨.

  2. 웹 키패드 샘플은 GET 요청이긴 했지만, fetch()를 통해 RSA 공개키를 받아오고 복호화 요청을 하고 있었음.

    1. 다만 웹 개발 환경에서는 Vite의 프록시 서버를 사용하고 있었음.

    2. 즉, 브라우저에서는 같은 사이트 요청으로 처리되어 쿠키가 정상적으로 전송되었던 것.

  3. 리액트 네이티브에서는 배포된 웹사이트를 WebView로 띄우고 있었고, 배포 환경에서는 프록시 없이 키패드 서버 URL을 직접 호출하고 있었음.

    • 배포 웹사이트와 키패드 서버가 서로 다른 Site로 평가되면서 크로스 사이트 fetch() 요청이 되었고, SameSite=Lax로 처리된 JSESSIONID가 복호화 요청에 동봉되지 않았음.
  4. 따라서 배포 환경에서도 동일한 프록시 경로를 유지하거나, 키패드 서버의 세션 쿠키를 크로스 사이트 요청에 맞게 SameSite=None; Secure로 설정해야 했음.

    • 직접 호출 구조에서는 이와 별도로 fetch의 credentials와 서버의 credentialed CORS 조건도 충족되어야 함.
    • 당시에는 세션 전달을 막고 있던 마지막 조건이 SameSite였기 때문에 서버의 쿠키 설정을 수정하는 방식을 선택함.

Comments