- 프로젝트: SNU FESTIVAL
- 키워드: .env, react environment variables, security, chrome devtools sources, firebase auth, firestore
- 상황
- 프로젝트에서 로그인 기능은 firebase auth 의 google login 을 사용하고 있고, 데이터 CRUD는 firestore 를 사용하고 있다.
- CRA 환경에서 firebase api key 값을 .env 파일에 분리하여 저장하고있다.
- .env 파일이 보안을 위해 사용한다고 알려져있지만, 개발자 도구 source를 통해 충분히 노출될 가능성이 있다.
이를 막기 위해선 백엔드의 도움이 필요하지만, SNU FESTIVAL 프로젝트는 1인 개발이므로 firebase 의 보안 기능을 최대한으로 이용해 악용을 막고자했다.
- 해결방법
- firebase login을 승인된 도메인에서만 허용한다.
- firestore rule 에서 firebase auth 인증이 되어있는 사용자만 데이터를 조작할 수 있도록 설정한다.
즉 firebase 인증은 승인된 도메인에서만 가능하고, 인증이 되어야지만 데이터를 조작할 수 있기 때문에, api key가 유출되어도 데이터 접근은 막을 수 있다.
위의 사진은 특정 collection에 대해 로그인된 유저만 새로운 문서를 만들 수 있고, 본인이 만든 문서만 read, update 할 수 있도록 설정한 예시이다.
- firebase login을 승인된 도메인에서만 허용한다.
- 한 걸음 더
- 카카오톡 로그인/공유하기 기능을 사용할 때에도 비슷한 과정을 거친다. 사이트 도메인에 등록된 곳에서만 해당 기능이 정상 작동한다.
- 네이버 map 을 사용할 때에도 비슷한 과정을 거친다.
secret key 가 노출되더라도 승인된 도메인에서만 naver api 를 사용할 수 있다.
- 카카오톡 로그인/공유하기 기능을 사용할 때에도 비슷한 과정을 거친다. 사이트 도메인에 등록된 곳에서만 해당 기능이 정상 작동한다.
- 두 걸음 더
- 상황
- api key 이외에 SNU FESTIVAL 프로젝트에서 숨겨야하는 값이 또 있었다.
- 미궁게임(https://snu-festival.web.app/activity/mini/riddle)의 정답을 숨겨야하는데, 정답을 코드에 하드코딩하면 난독화를 한다고 하더라도 chrome devtools source 어딘가에 정답이 노출될 것이다.
- 정답을 외부(서버, firebase 등)에 저장한 뒤 GET 요청으로 받아올 수 있겠지만, 미궁게임의 짧은 정답 'string' 만을 위해 네트워크를 추가적으로 사용하고 싶지는 않았다.
- 해결방법
- 비밀번호를 DB에 저장하는 것과 같은 원리로 js-sha256 라이브러리를 이용하여 정답의 hash값을 구한다.
- hash값만 프로젝트 코드에 하드코딩한다.
const answers = [ '07436abdfc015b3d6e7f6236e4817639b24bfb77e68adfb779ace94e8d08c047', '4ea140588150773ce3aace786aeef7f4049ce100fa649c94fbbddb960f1da942', 'a27db16581bce5f90e4e7d08e10f861d0c6986a01d80babea22f6af4e5774ff1', ];
- 미궁게임 정답 입력창에서 사용자가 정답을 입력하면, 해당 문자열의 hash값을 구한 뒤 answers의 hash값과 비교한다.
- 상황
- 의의
- 프론트엔드단에서 중요한 값을 완벽하게 숨기는 것은 어렵지만, key가 노출되어도 악용할 수 없도록 잘 대응해두자.
- hash를 이용하여 퀴즈의 정답을 숨기는 로직을 간단하게 구현할 수 있었다.
'프론트엔드' 카테고리의 다른 글
번들링 최적화를 통해 import cost 줄이기(1) (0) | 2021.11.25 |
---|---|
Chrome과 안드로이드 기기를 유선/무선 연결하기 (0) | 2021.11.23 |
safari inset, intersection observer 크로스 브라우징하기 (0) | 2021.11.18 |
css animation steps로 Spinner 구현하기 (0) | 2021.11.17 |
Firebase storage 파일 재귀적으로 삭제하기 (0) | 2021.11.13 |