종종 aws secret key
, github secret
등을 공개 github 저장소에 commit 해버린 경험이 있을 것 이다.
나 역시도 이전 직장에서 aws secret key
를 github에 push 해버린 탓에 AWS로부터 연락을 받고 급히 수습하며 전사메일로 스미마셍을 외친 경험이 있다.
이번 글에서는 git을 이용하는 과정에서 민감 정보 유출 재발 방지책으로 사용했던 git-secrets를 한번 소개해볼까 한다.
git-secret은 password등 민감한 정보를 git repository에 committing하는 것을 방지해주는 도구이다.
이것을 통해 엔지니어가 인지하지 못하고 민감 정보를 commit하려 시도하면 git-secret
가 이것을 막아준다.
Prevents you from committing passwords and other sensitive information to a git repository.
--no-ff
merges 등을 검사하고reject
한다.git-secrets scans commits, commit messages, and --no-ff merges to prevent adding secrets into your git repositories.
If a commit, commit message, or any commit in a --no-ff merge history matches one of your configured prohibited regular expression patterns, then the commit is rejected.
이러한 것은 git hooks(?)를 이용해 구현된 것 같다.
git-secrets의 github에 가보면 여러 설치 방법이 있지만 여기서는 mac을 기준으로 설명한다.
누구나 사용하는 brew
를 통해 간단히 설치 가능하다.
brew install git-secrets
여기서 설치가 끝나는 것이 아닌, git hooks도 설치해줘야 한다.
기본적으로는 원하는 repository에만 설치해볼 수 있다.
cd /path/to/my/repo
git secrets --install
git secrets --register-aws
---
✓ Installed commit-msg hook to .git/hooks/commit-msg
✓ Installed pre-commit hook to .git/hooks/pre-commit
✓ Installed prepare-commit-msg hook to .git/hooks/prepare-commit-msg
설치되는 git hook들은 아래와 같다.
git secrets --register-aws --global
git secrets --install ~/.git-templates/git-secrets
git config --global init.templateDir ~/.git-templates/git-secrets
git secrets --add-provider -- cat /path/to/secret/file/patterns
설치 방법은 위에서 알아보았으니, 이제 한번 만져보자.
brew install은 건너뛰고... 특정 repository에 git hooks를 추가한다. aws pattern도 추가했다.
$ cd ~/Desktop/geunje-git-secrets
$ git secrets --install
✓ Installed commit-msg hook to .git/hooks/commit-msg
✓ Installed pre-commit hook to .git/hooks/pre-commit
✓ Installed prepare-commit-msg hook to .git/hooks/prepare-commit-msg
$ git secrets --register-aws
OK
그 후 hooks를 살펴보니 이것저것 많이 생성되어있다.
위에서 설명한 비밀 정보 catch를 위한 hook들인 것 같다.
$ ls .git/hooks
applypatch-msg.sample fsmonitor-watchman.sample pre-commit pre-push.sample prepare-commit-msg update.sample
commit-msg post-update.sample pre-commit.sample pre-rebase.sample prepare-commit-msg.sample
commit-msg.sample pre-applypatch.sample pre-merge-commit.sample pre-receive.sample push-to-checkout.sample
그럼 pattern들은 어디에 있을까? config를 살펴보니 secrets 섹션이 생긴 것을 확인했다.
$ view .git/config
(...omit...)
[secrets]
providers = git secrets --aws-provider
patterns = (A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}
patterns = (\"|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)(\"|')?\\s*(:|=>|=)\\s*(\"|')?[A-Za-z0-9/\\+=]{40}(\"|')?
patterns = (\"|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?(\"|')?\\s*(:|=>|=)\\s*(\"|')?[0-9]{4}\\-?[0-9]{4}\\-?[0-9]{4}(\"|')?
allowed = AKIAIOSFODNN7EXAMPLE
allowed = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
한번 pattern에 위반하는 commit을 시도해보자.
이번 예제는 실수로 aws credential을 포함해 commit을 시도하려 하는 상황이다.
$ ls
README.md some_configure.yaml
$ cat some_configure.yaml
aws_access_key_id = AKIBUZBRM12345DBPPs
aws_secret_access_key = 4KOpH3Gdew30anF9123s3LTECwkRhzlx4Ys9rney
$ git add .
$ git commit -m 'test commit for git secrets'
some_configure.yaml:2:aws_secret_access_key = 4KOpH3Gdew30anF9123s3LTECwkRhzlx4Ys9rney
[ERROR] Matched one or more prohibited patterns
Possible mitigations:
- Mark false positives as allowed using: git config --add secrets.allowed ...
- Mark false positives as allowed by adding regular expressions to .gitallowed at repository's root directory
- List your configured patterns: git config --get-all secrets.patterns
- List your configured allowed patterns: git config --get-all secrets.allowed
- List your configured allowed patterns in .gitallowed at repository's root directory
- Use --no-verify if this is a one-time false positive
이외에도 git-secrets은 여러 옵션을 제공하고 있다.
그중 --scan
옵션이 있는데, 이건 repository file을 scan하여 pattern과 매치하는 민감 정보가 있는지 확인한다.
$ git secrets --scan --no-index
some_configure.yaml:2:aws_secret_access_key = 4KOpH3Gdew30anF9123s3LTECwkRhzlx4Ys9rney
[ERROR] Matched one or more prohibited patterns
Possible mitigations:
- Mark false positives as allowed using: git config --add secrets.allowed ...
- Mark false positives as allowed by adding regular expressions to .gitallowed at repository's root directory
- List your configured patterns: git config --get-all secrets.patterns
- List your configured allowed patterns: git config --get-all secrets.allowed
- List your configured allowed patterns in .gitallowed at repository's root directory
- Use --no-verify if this is a one-time false positive
다양한 scan 예제들은 git hub에서 확인해볼 수 있다.
git-secrets은 awslab에서 만든 툴이라 그런지 기본적으로 aws credential은 설치해서 사용할 수 있다.
하지만 나는 github personal access token도 막아버리고 싶다.
이런건 바로 --add
옵션을 이용해 pattern을 추가해볼 수 있다.(더 많은 예제는 여기)
$ git secrets --add 'ghp_[A-Za-z0-9]{36}'
이후 config를 다시 확인해보면 pattern이 추가된 것을 알 수 있다.
$ cat .git/config
(...omit...)
[secrets]
providers = git secrets --aws-provider
patterns = (A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}
patterns = (\"|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)(\"|')?\\s*(:|=>|=)\\s*(\"|')?[A-Za-z0-9/\\+=]{40}(\"|')?
patterns = (\"|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?(\"|')?\\s*(:|=>|=)\\s*(\"|')?[0-9]{4}\\-?[0-9]{4}\\-?[0-9]{4}(\"|')?
allowed = AKIAIOSFODNN7EXAMPLE
allowed = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
patterns = ghp_[A-Za-z0-9]{36}
이후 some_configure.yaml
의 내용을 가짜 github token으로 바꾸면 똑같이 reject되는 것을 볼 수 있다.
$ ls
README.md some_configure.yaml
$ cat some_configure.yaml
git_PAT = ghp_TESTYcplhZ8va5E6xiK8cJIE8KGH6J1TESZl
$ git add .
$ git commit -m 'test commit for git secrets'
some_configure.yaml:1:git_PAT = ghp_TESTYcplhZ8va5E6xiK8cJIE8KGH6J1TESZl
[ERROR] Matched one or more prohibited patterns
Possible mitigations:
- Mark false positives as allowed using: git config --add secrets.allowed ...
- Mark false positives as allowed by adding regular expressions to .gitallowed at repository's root directory
- List your configured patterns: git config --get-all secrets.patterns
- List your configured allowed patterns: git config --get-all secrets.allowed
- List your configured allowed patterns in .gitallowed at repository's root directory
- Use --no-verify if this is a one-time false positive
위에서 설명한 예제는 local에 있는 특정 repository에 위에서만 진행한 예제이다.
global하게 적용하고, 모든 local repository에 적용하고 싶다면 Advanced 설정
을 조합하면 될 것 같다.
사실 한번 설정해두고 오랫동안 잘 만지지 않아서 숙련도가 떨어질지도 모른다.
당장 provider라는 개념이 있는데 이게 뭘 뜻하는 것 인지, 굳이 필요한지 애매한 상황이다.
때문에 이 글에 대한 피드백은 언제나 환영이고 기다리고 있다.
끗.