git-secrets을 이용한 민감 정보 유출 commit 방지

KEUN·2022년 9월 27일
1
post-thumbnail

종종 aws secret key, github secret등을 공개 github 저장소에 commit 해버린 경험이 있을 것 이다.

나 역시도 이전 직장에서 aws secret key를 github에 push 해버린 탓에 AWS로부터 연락을 받고 급히 수습하며 전사메일로 스미마셍을 외친 경험이 있다.

이번 글에서는 git을 이용하는 과정에서 민감 정보 유출 재발 방지책으로 사용했던 git-secrets를 한번 소개해볼까 한다.

git-secrets

개요


git-secret은 password등 민감한 정보를 git repository에 committing하는 것을 방지해주는 도구이다.
이것을 통해 엔지니어가 인지하지 못하고 민감 정보를 commit하려 시도하면 git-secret가 이것을 막아준다.

Prevents you from committing passwords and other sensitive information to a git repository.

- https://github.com/awslabs/git-secrets

어떻게 방지를 해주냐 하면

  1. commit, commit message, --no-ff merges 등을 검사하고
  2. 그곳에 금지된 정규 표현식에 일치하는 문자가 있다면 commit을 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들은 아래와 같다.

  • pre-commit:
    - Used to check if any of the files changed in the commit use prohibited patterns.
  • commit-msg:
    - Used to determine if a commit message contains a prohibited patterns.
  • prepare-commit-msg:
    - Used to determine if a merge commit will introduce a history that contains a prohibited pattern at any point. Please note that this hook is only invoked for non fast-forward merges.

Advanced 설정

  • git-secrets은 global 설정을 통해 앞으로 clone할 repository에 자동으로 git-secrets을 적용할 수 있다.
git secrets --register-aws --global
  • local에 존재하는 모든 repository에 hook을 추가할 수 있다.
git secrets --install ~/.git-templates/git-secrets
git config --global init.templateDir ~/.git-templates/git-secrets
  • custom provider pattern을 추가할 수 있다.
git secrets --add-provider -- cat /path/to/secret/file/patterns

💻hands-on


설치 방법은 위에서 알아보았으니, 이제 한번 만져보자.

설치 및 설정

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을 시도하려 하는 상황이다.

  • repository에 credential 정보가 담긴 file을 두고
$ ls
README.md           some_configure.yaml

$ cat some_configure.yaml
aws_access_key_id = AKIBUZBRM12345DBPPs
aws_secret_access_key = 4KOpH3Gdew30anF9123s3LTECwkRhzlx4Ys9rney
  • commit을 시도하면? 아래와 같이 commit이 거부된다.
$ 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
  • vscode에서 commit을 시도해도 동일하다.

심화 사용법 - pattern scan

이외에도 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에서 확인해볼 수 있다.

심화 사용법 - pattern 추가

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라는 개념이 있는데 이게 뭘 뜻하는 것 인지, 굳이 필요한지 애매한 상황이다.

때문에 이 글에 대한 피드백은 언제나 환영이고 기다리고 있다.

끗.


참고: 나의 일본 생활 Tech blog

profile
Let's make something for comfortable development

0개의 댓글