4분
보안 점검 - API 키가 GitHub에 올라간 적 있는가?
Day 4: GitHub 포트폴리오 - 코드가 아닌 커리어를 보여줘라
보안 점검 - API 키가 GitHub에 올라간 적 있는가?
발표 & 포트폴리오 > Day 4: GitHub 포트폴리오 - 코드가 아닌 커리어를 보여줘라
학습 목표
- GitHub에 민감 정보가 노출되는 경로를 이해한다
- git 이력에서 민감 정보를 완전히 제거하는 방법을 학습한다
- .env.example 패턴을 활용한 안전한 설정 관리를 파악한다
API 키가 GitHub에 올라간 적 있는가?
실제 사고 사례:
━━━━━━━━━━━━━━
1. 개발자가 .env 파일을 실수로 커밋
2. .gitignore에 .env를 추가하고 다시 커밋
3. "이제 안전하겠지" 라고 생각
하지만:
git log에 과거 커밋이 남아있다.
누구나 git log -p 로 과거 커밋을 볼 수 있다.
.gitignore는 "앞으로" 추적을 안 할 뿐,
"과거" 이력은 삭제하지 않는다.
결과:
- 몇 시간 후 API 키가 악용됨
- AWS 청구서: $12,000 (비트코인 채굴)확인해야 할 민감 정보
| 유형 | 예시 | 위험도 |
|---|---|---|
| API 키 | OPENAI_API_KEY=sk-... | 높음 (비용 발생) |
| DB 비밀번호 | NEO4J_PASSWORD=... | 높음 (데이터 유출) |
| JWT Secret | JWT_SECRET=... | 높음 (인증 우회) |
| 클라우드 키 | AWS_SECRET_ACCESS_KEY=... | 매우 높음 |
| 개인 정보 | 이메일, 전화번호 (코드 주석) | 중간 |
점검 방법
1. 현재 파일 점검
# .env 파일이 추적되고 있는지 확인
git ls-files | grep -i env
# API 키 패턴 검색
grep -rn "sk-" --include="*.py" --include="*.ts"
grep -rn "password" --include="*.py" --include="*.yml"
grep -rn "secret" --include="*.py" --include="*.yml"
2. git 이력 점검
# 과거 커밋에서 민감 정보 검색
git log -p --all -S "sk-" -- "*.py" "*.env"
git log -p --all -S "password" -- "*.py" "*.yml"
3. git 이력에서 완전 제거 (필요 시)
BFG는 최신 커밋(HEAD)을 보호하므로, 현재 트리에 .env가 남아 있으면
protected commit이라며 거부한다. 그리고 git clone --mirror로 받은
베어 저장소에서 실행하는 것이 정식 절차다. 순서가 바뀌면 실행되지 않는다.
# BFG Repo-Cleaner 사용
# https://rtyley.github.io/bfg-repo-cleaner/
# 1. 현재 트리에서 먼저 추적을 끊고 커밋한다 (BFG가 HEAD를 보호하므로)
git rm --cached .env
git commit -m "chore: stop tracking .env"
git push
# 2. 베어 저장소를 미러로 복제한다
git clone --mirror https://github.com/<your-id>/<repo>.git repo.git
# 3. 미러 저장소에서 파일을 이력째 삭제
bfg --delete-files .env repo.git
# 4. 또는 특정 텍스트 교체
bfg --replace-text passwords.txt repo.git
# 5. 정리
cd repo.git
git reflog expire --expire=now --all
git gc --prune=now --aggressive
# 6. 되돌린 이력을 반영 (미러 저장소이므로 --force가 아니다)
git push
.env.example 패턴
# .env (절대 커밋하지 않음, .gitignore에 포함)
OPENAI_API_KEY=sk-abcdef123456
NEO4J_URI=bolt://localhost:7687
NEO4J_PASSWORD=mysecretpassword
DATABASE_URL=postgresql://user:pass@localhost/db
# .env.example (커밋함, 어떤 변수가 필요한지 안내)
OPENAI_API_KEY=your-openai-api-key-here
NEO4J_URI=bolt://localhost:7687
NEO4J_PASSWORD=your-neo4j-password
DATABASE_URL=postgresql://user:password@localhost/dbname
# .gitignore
.env
.env.local
.env.production
*.pem
*.key
보안 체크리스트
공개 전 필수 확인
━━━━━━━━━━━━━━━
□ .env 파일이 .gitignore에 포함되어 있는가?
□ .env.example 파일이 존재하는가?
□ git ls-files에 .env가 추적되고 있지 않은가?
□ 코드에 API 키가 하드코딩되어 있지 않은가?
□ git log에 과거 민감 정보 이력이 없는가?
□ docker-compose.yml에 비밀번호가 직접 쓰여있지 않은가?
□ 주석에 개인 정보(이메일, 전화번호)가 없는가?핵심 정리
- .gitignore만으로는 과거 이력을 지울 수 없다
- git log -p -S로 이력에 민감 정보가 있는지 반드시 확인
- .env.example 패턴으로 필요한 변수를 안내
- 공개 전 보안 체크리스트 전체 확인
AI로 학습하기 — 꿀팁
git 이력 민감 정보 노출 검증AI 학습 팁
API 키가 과거 커밋에 존재하면 현재 .gitignore에 있더라도 이력에서 노출됩니다. AI로 탐지 명령어와 완전 제거 절차를 정확히 검증하세요.
다음 git log --all -p 출력 일부를 분석해서 민감 정보 노출 여부를 점검해줘. 탐지 대상: API 키 패턴(sk-*, AIza*, eyJ*), 비밀번호 패턴(password=, passwd=, secret=), DB 연결 문자열(postgresql://, mysql://), 내부 IP 주소(10.x.x.x, 192.168.x.x). 발견 시: 해당 커밋 해시 + 파일경로 + 제거 방법(git filter-branch 또는 BFG Repo-Cleaner 명령어) 순서대로 알려줘. 발견 없으면 '클린'으로 확인해줘: [git log 출력 일부 붙여넣기]
이 팁이 도움이 됐나요?