서론
알리고 올리고 로그인 관리를 로컬 스토리지를 활용하여 구현할지, 세션을 활용할지 쿠키를 사용할지 고민하면서 우선 각 스토리지가 어떤 장점이 있고 단점이 있으며 어느 부분이 보완된 것이며 보안에 취약한 점은 무엇인지 정리해보려고 한다.
본론
0. 브라우저 저장소의 배경
인터넷 특성 중 무상태성이 있기 때문에 클라이언트에서 상태를 보존하지 않는다. 그래서 클라이언트에서 상태를 저장하고 필요할 경우 데이터를 꺼내 확인하는 방식으로 서버 부하를 낮추기 위해 쿠키와 웹 스토리지가 탄생하였다. 결국 이것도 비용문제인 것 같다.
1. 쿠키
탄생 배경
1994년 루몬틀리가 전자상거래 앱을 개발하는데 사용자의 상태를 저장하기 위해 사용하는 방식에서 시작되었다고 한다.
정의
- 서버가 클라이언트에 전송하는 작은 데이터 조각
- 만료 기간이 있는 키와 값이 들어가있는 작은 데이터 파일
- http의 특징인 stateless와 connectionless로 인해 서버가 사용자의 정보를 알기 위해 사용자가 웹사이트에 접속할 때 생성되는 크기가 작은 문자열 파일이다.
쿠키 생성 방법
서버에서 만들 수 있다.
HTTP 요청 수신시, 응답과 함께 set-cookie 헤더를 전송할 수 있다. 쿠키는 브라우저에 저장하고 같은 서버에 의해 만들어진 요청들의 Cookie HTTP 헤더 안에 포함되어 전송한다. 만료일과 지속시간도 명시할 수 있고 만료된 쿠키는 더이상 보내지지 않는다.
서버에서 쿠키를 만들어준다.
1. SameSite : None , Lax, Strict (같은 도메인에서만 저장하겠다는 정책)
app.use(session({
secret :'string',
resave : false,
saveUninitialized : true,
cookie: {
maxAge : 24 * 6 * 60 + 1000,
sameSite : 'lax',
httpOnly : true
},
}))
- none : 크로스 사이트 요청의 경우에도 항상 전송된다.
- Lax : get || option에 한해서 CORS를 허락 (설정은 백앤드)
- Strict : 가장 보수적인 정책이고 Strict로 설정된 쿠키는 동일한 도메인의 요청에만 전송된다. 즉 서드 파티 쿠키는 전송되지 않고 퍼스트 파티 쿠키만 전송된다.
- httpOnly : JS로 접근하지 못하게 하는 설정 , HTTP 속성으로만 접근
Set-Cookie와 Cookie 헤더
Set-Cookie HTTP 응답 헤더는 서버로부터 사용자 에이전트로 전송된다.
특징 및 종류
- 최대 4KB의 문자열을 가지고 있는 데이터이다.
- 도메인당 최소 50개까지 지원한다.
- 브라우저당 최소 3천개까지 보관이 가능하다.
- 만료 시간 설정이 가능하다. 만약 설정하지 않으면 브라우저 종료시 삭제된다.
- 퍼스트파티쿠키 : 쿠키의 도메인과 접속한 도메인 일치한 쿠키
- 세션에서 사용자의 세션 아이디 값을 가지고 있는 세션 쿠키
- 암호화하여 사용자와 서버가 주고 받는 보안 쿠키
- 사용자에게 맞춤형 광고를 제공할 때 사용하는 서드파티쿠키
단점
- 4KB의 적은 용량
- HTTP 요청시 모든 쿠기가 자동으로 전달된다. 결과적으로 불필요한 트래픽 양 증가
- XSS 공격에 취약
- XSRF 공격에 취약
보안 강화를 위한 방법
- HttpOnly 속성:Cookie를 HTTP에서만 사용할 수 있고 브라우저에서는 접근할 수 없도록 하여 XSS같은 Cookie 탈취를 방지하는 HTTPOnly 속성도 있다. 즉 JavaScript의
Document.cookie
(en-US) API에 접근할 수 없습니다.
- SameSite 속성 : XSRF 공격을 막기 위해선 동일한 도메인 요청에만 쿠키를 전송할 수 있게 해주고 여러 프로퍼티를 통해 제어할 수 있다.
- Secure 속성 : HTTPS로 통신하는 경우에만 쿠키에 전송할 수 있도록 할 수 있다.
관련있는 개념
CORS : CORS 정책이 쿠키를 다룰때 많이 등장하는 에러일뿐 상호간의 연관성은 없다.
2. 웹 스토리지
브라우저 안에 데이터를 저장할 수 있는 공간 핵심은 보안이 중요하지 않은 데이터를 클라이언트 영역에서 저장하게 해주는 것이다. 쿠키의 문제를 해결하고자 HTML5에서 나온 기술로 저장 가능한 데이터의 용량과 개수, 보안 관점에서 쿠키의 데이터 저장 기술보다 더 좋다.
쿠키의 문제점을 다시 보면 첫 번째 4KB의 적은 용량 두번 째HTTP 요청시 모든 쿠기가 자동으로 전달된다는 것 세번 째. XSS 공격에 취약
한 것. 마지막으로 XSRF 공격에 취약도 취약하다는 것이다.
이것을 어떻게 해결하는가
공통적인 브라우저 스토리지 특징
- 5MB의 정보 저장 가능
- 자동으로 서버에 전송되지 않는다. (쿠키 트래픽 문제 해결)
- 오리진 단위로 접근이 제한 ([[CSRF]]로 부터 안전)
Q. 오리진 단위란? 프로토콜, 도메인,
지속성을 기준으로 크게 로컬 스토리지와 세션 스토리지로 구성되어있고 하나씩 살펴보자
2-1. 로컬 스토리지
저장 범위
도메인 별
특징
- 브라우저에 반 영구적인 스토리지이며 브라우저를 종료해도 데이터가 유지되는 특징이 있다.
- 개발자가 로컬 스토리지의 데이터를 갱신하지 않는다면 로컬 스토리지에 담긴 데이터는 사라지지 않는다.
용도
- 자동 로그인 기능
2-2. 세션 스토리지
저장 범위
도메인과 브라우저 탭별 가능
특징
- 브라우저의 탭 윈도우 단위로 생성이 되는 즉 일시적인 스토리지다. 탭 윈도우를 닫게 되면 스토리지에서 해당 데이터가 사라지는 특징이 있다.
- 5MB 이상으로 쿠키에 비해 상대적으로 크고 전송 가능한 데이터의 개수도 제한이 없다. (쿠키의 약 1250배)
활용
최근 본 상품 기록, 조회한 상품 기록, 장바구니
브라우저 스토리지의 단점
- 만료 기간을 설정할 수 없다.
- 동기적으로 실행한다. (용량이 큰 데이터를 저장할 경우 IndexedDB 고려해야한다.)
- 미지원 브라우저 사파리 시크릿 모드일 경우 에러 처리가 필요하다
- XSS 공격에 취약하다.
3. 쿠키와 웹 스토리지 차이 정리
- 쿠키는 매번 서버로 쿠키를 전송하지만 웹 스토리지는 클라이언트에서 값을 저장할 뿐 서버로 전송하진 않는다.
- 쿠키는 XSRF에 안전하지만 XSS에는 취약하다
- 반대로 웹 스토리지는 XSS에 안전한 편이지만 XSRF 공격에는 취약하다
4. 위의 정보들 종합해서 정리해보는 저장 기준
- 데이터 용량
- 만료기간 설정이 필요한지
- 매번 요청에 필요한 데이터인지
- 어느 보안에 신경 쓸지 (XSS, XSRF)
결론
- 이번 프로젝트에서는 서버 개발자가 첫 프로젝트이기에 최대한 서버 로직에 의존적인 부분은 사용하지 않는게 좋을 것 같다고 판단했다. 그래서 따로 서버에서 설정해주지 않아도 되는 로컬 스토리지를 사용하려고 한다.
- HTTP 특징인 무상태성으로 인해 유저는 페이지를 이동할때 마다 로그인을 해야하는 문제가 발생하였다. 그 문제를 쿠키 및 브라우저 저장소를 통해 해결할 수 있게 됐다.
참고 자료
- 유튜브 코드온 : https://www.youtube.com/watch?v=5s--sLWzuZc