메일이 하나 왔다. 제목은 [scseong/movie-app] Bearer Token exposed on GitHub.

오늘 한 일

  • Github 저장소에 올린 Bearer Token 숨기기

들어가며

내배캠 3주차 자바스크립트 개인 과제를 마치고 리팩토링 하던 중 메일을 확인하는데..

사건의 발단..

메일의 내용은 다음과 같다.

GitGuardian has detected the following Bearer Token exposed within your GitHub account.
Details

- Secret type: Bearer Token
- Repository: scseong/movie-app
- Pushed date: October 19th 2023, 07:56:59 UTC

Fix This Secret Leak

그렇다. 실제 TMDB API를 호출하기 위해 Access token Auth을 js 파일에 넣어서 사용한 것이 화근이었다. 처음엔 git에는 올리지 않고 환경변수를 사용할 계획이었다. 패키지 설치없이 환경변수를 사용할 수 있지 않을까 해서 여러 시도를 했지만 dotenv 라이브러리를 설치해야 했다. “간단한 프로젝트이고 하루 요청 한계도 있는데 그냥 올리지” 라는 생각으로 push 해버렸다.

메일을 따라 가보니 Github 계정과 GitGuardian 연동 권한 설정을 하란다. 대충 이름을 보니 민감한 데이터를 추적하고 관리해주는가보다 싶었다. (사용 설정도 안했는데 어떻게 알고 메일을 보냈지)

역시나 그냥 올렸던 Access token Auth이 문제가 되니까 빨리 수정하라는 것. 개발하며 빨간색을 보면 괜히 불안해진다. 처음에는 대수롭지 않게 생각했는데 GitGuardian에 대해 검색하다보니 ‘github 해킹 사건’, ‘API key를 올려서 과금 당한 사건’ 등을 보니 숨기기로 결정했다. 개발하며 겪을 수 있는 상황이니 이번 기회에 적용하기로 했다.

GitGuardian에서 버튼 하나 누르면 github 저장소의 해당 문자가 지워질 것을 기대했지만 그런 일은 일어나지 않았다. 방법은 알려줬다. Git Clean, Git Remove file from commit - Cheatsheet - GitGuardian Blog

Github 저장소에서 중요한 데이터 제거하기

자 먼저 해야할 일을 살펴보자.

▶ 자세히 보기: RewritingYourGitHistory-Cheatsheet-Final_weq1l2.pdf

먼저 단계에 따라 상황에 맞게 해야할 일을 명확하게 설명하고 있다.

STEP 01. “Select a scenario that applies at Step 1”

세 가지의 상황이 있다. secret key가 포함된 커밋을 푸시하지 않은 경우, 푸시했지만 혼자 작업하는 경우와 팀으로 작업하는 경우. 그 중 혼자 작업하는 경우 상황 B에 속했다.

그런데 당시 정상적 판단이 안되어 상황 C로 했다. 어차피 그 당시는 최신화 상태였고 단순 clone해서 새 프로젝트를 만든 것이므로 문제가 있진 않았을 것이라 생각.

STEP 02. In all cases move to Step 2

어느 케이스에 속하냐 살펴봤다. 복잡하대.

Which is applicable?

Secret is not in last commit 
therefore it s complicated. install git-filter-repo

이미 오래전 푸시해서 노출되고 있었다. git-filter-repo 설치하자..

git-filter-repo 설치하기

pdf에서 친절히 링크를 걸어놔서 따라가봤다.

GitHub - newren/git-filter-repo: Quickly rewrite git repository history (filter-branch replacement)

설치방법에 INSTALL.md로 갔다. 한국어로 번역을 누르고 살펴보니 git-filter-repo 파일을 다운로드 하란다. 링크를 걸어둔 저장소로 가서 로컬 저장소에 clone 했다. 이까지는 수월했다.

$ git clone https://github.com/newren/git-filter-repo.git

git-filter-repo is a single-file python script, which was done to make installation for basic use on many systems trivial: just place that file into your $PATH. - GitHub - newren/git-filter-repo: Quickly rewrite git repository history (filter-branch replacement)

가이드를 살펴보니 바로 위에 전제조건이 git과 python이 설치되어 있어야 했다. git(bash)은 이미 설치했었고 파이썬은 오래 전에 써서 설치가 되어있었다. 위의 명령을 실행했다. (무슨 일이 일어났는지는 기억나지 않음.)

그리고 가이드 스크롤을 내려보니 자세한 설명이 있었다. filter-repo를 디렉토리에 설치하라고 했다. $ git --exec-path 명령어를 사용하니 주소가 하나 나왔다. git 실행 경로를 보여주거나 설정하는 폴더 주소를 알려주는 명령어. 아까 다운 받은 git-filter-repo 파일을 방금 주소로 붙여 넣었다.

그런 다음 명령을 실행하란다. 실행하니 밍밍하게 ‘Python’ 이라는 출력만 나왔다.

$ python3 git-filter-repo --analyze

다음 단계..

아직 남았다. “Is the secret a portion of a larger file or a file that needs to be removed?”

자바스크립트 파일을 삭제할 수는 없고 해당 라인 1줄만 지워야 한다. 다음 행동으로 넘어갔다.

Portion of a file: Create file «replacement.txt» Use format: ORIGINAL==>REPLACEMENT

replacement.txt 파일을 만들었다. 파일을 명시된 텍스트를 어떻게 바꿀 것인지 정의한다. 예를 들어 ‘abcdef’를 찾아 오른쪽 123으로 변경한다. 다른 텍스트로 바꾸지 않으려면 빈 칸으로 둔다. 비워두면 ***REMOVED***'가 된다.

abcdef==>123
abcdef

그래서 replacement.txt 파일에 깃허브에 올린 Access Token 문자열을 복사해서 붙여넣고 저장했다. replacement.txt 파일은 프로젝트 상위 디렉터리에 있어야 한다.

실행만 남았다

$ git filter-repo --replace-text ../replace.txt --force 을 프로젝트 루트 폴더에서 git bash를 열어 실행했다.

결과는 “git: ‘filter-repo’ is not a git command.”. 순조롭게 될리가 없다.

다시 git-filter-repo 설치하기

에러를 구글링하면서 다시 이유를 찾아봤다. 이 문제만 1시간은 걸린 듯.

(지금 보니까 알려준대로 했으면 되는데 왜 그땐 눈에 들어오지 않았을까.)

무수한 레퍼런스를 따라 해보며 실행한 것 중 하나 - How do you install git-filter-repo?

$ python3 -m pip install --user git-filter-repo`

그랬더니 warning이 떴다. 버전 어쩌구저쩌구.. 업데이트 했다.

pip install --upgrade pip

pip list 해보니 git-filter-repo가 있었다.

설치된 것을 보고 다시 명령어를 실행했다.

$ git filter-repo --replace-text ../replacement.txt

미적지근하게 또 ‘Python’ 한 단어만 출력이 나왔다. 보통 git 명령을 치면 촤르르륵 나오면서 진행이 되는데 아무일도 일어나지 않았다. git filter-repo -h 을 입력하면 help 문이 나온다는데 그것도 아무일도 일어나지 않았다. 후.. 또 찾아봤다.

Modifying PATH, making the script executable: For some reason lots of Windows users have a hard time modifying their PATH and/or making scripts executable. You can skip that step by just using python3 git-filter-repo instead of git filter-repo in your commands.

python3 git-filter-repo도 해보고 git filter-repo도 다해봤는데 실패. 그러다가 비공개로 작업하던 레포 공개로 전환하기 위해 스크릿 파일 삭제하기 - 친성의 블로그 scoop을 통해 설치하면 문제없다고 해서 scoop을 설치했다. powershell로 실행. (이전에 git-filter-repo 삭제했다. pip uninstall git-filter-repo )

> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser # Optional: Needed to run a remote script the first time
> irm get.scoop.sh | iex
🚨 Error
Running the installer as administrator is disabled by default, 
see https://github.com/ScoopInstaller/Install#for-admin for details.

설치 중 오류 또 구글링 - scoop 설치 -> 해결

iex "& {$(irm get.scoop.sh)} -RunAsAdmin"

이후 filter-repo 설치

scoop install git-filter-repo

$ git filter-repo --replace-text ../replacement.txt

또 아무 일 일어나지 않았다. 다시 구글링하는데 그제서야 아까 봤던 stackoverflow 글에서

명령을 사용하여 git --exec-pathGit exe가 설치된 위치를 확인하세요. 그런 다음 해당 디렉토리에서 git-filter-repo. 내 것은 대략 160KB 크기의 Python 스크립트입니다. 거기에 있으면 해당 파일을 열고 첫 번째 줄을 확인하십시오. ”python3”이 나열되어 있으면 “python”(3 제외)으로 변경해 보세요.

처음 다운받았던 git-filter-repo 파일을 열어 ctrl + f해서 python3을 모두 python으로 변경했다.

$ git filter-repo --replace-text ../replacement.txt

드디어….

STEP 03. Move to Step 3 that relates to the original scenario

Removing Sensitive Information from Git with git-filter-repo

이후의 과정은 수월했다!.

$ git remote add origin https://github.com/scseong/movie-app.git
$ git push -u origin develop –force

clone한 remote 저장소에 연결해주고 푸시했다!

Summary

  1. python, git bash 설치 (git bash 이용)

  2. GitHub - newren/git-filter-repo에서 ‘git-filter-repo’ 파일 다운로드(확장자 없음)

  3. $ git --exec-path 명령어 실행한 결과 폴더에 git-filter-repo 파일 넣기

  4. python3 -m pip install --user git-filter-repo: git-filter-repo 설치

  5. 프로젝트 폴더의 상위 폴더에 replacement.txt 생성. 지우고 싶은 문자열 저장.

  6. 프로젝트 루트 폴더에서 $ git filter-repo --replace-text ../replacement.txt` 실행

  7. 실패하면 git-filter-repo 파일 python3을 python으로 수정

  8. 5를 다시 실행

  9. github 저장소에 push. git push origin ..

느낀점

사실 글은 순서대로 잘 해결한 것 같지만 왔다갔다 몇 십개의 레퍼런스를 찾아보고 우여곡절을 겪으며 해결한 순서로 작성했다. 하루를 꼬박 써버렸다..

github에 secret key를 올린 결과는 끔찍했다. 하지만 덕분에 github 저장소에 올려 커밋이 쌓였을 때 지난 커밋에서의 문자열을 수정할 수 있는 방법을 알았다.

그리고 레퍼런스를 볼 떄는 꼭 순서대로 진행하고 자세히 살펴봐야한다는 교훈도 얻었다. 개발보다는 삽질을 해서 훨씬 피곤해진 하루가 되버렸다!

그리고 깃 그래프가 꼬여버렸다…

Reference

카테고리:

업데이트:

댓글남기기