덮어써도 원래 커밋은 남아 있어요
브랜치는 포스트잇이에요
브랜치는 커밋 더미 어딘가에 붙어서 "여기가 최신" 이라고 가리킬 뿐이에요.
공격자가 강제로 덮어쓴 건 커밋을 지운 게 아니라 포스트잇을 다른 데로 옮긴 겁니다. 원래 커밋은 그대로 있고, 주소를 잃어버렸을 뿐이에요.
그런데 GitHub 은 푸시가 들어올 때마다 옮기기 직전에 어디를 가리켰는지 적어둡니다.
before: 7f3a91c <- 잃어버린 주소
head: 9d2b04e되돌리기도 여기서 나와요. 포스트잇을 원래 자리에 도로 붙이면 됩니다.
순서
- 01
시간대 안의 푸시를 모아요
이벤트로 대상을 좁혀요. 조직 전체를 다 뒤지지 않습니다.
- 02
공격 직전 트리와 지금 트리를 맞대요
어떤 파일이 생기고, 바뀌고, 사라졌는지 나옵니다.
- 03
바뀐 파일을 전부 모아요
여기가 결과물이에요. 규칙과 무관하게 다 남습니다.
- 04
먼저 볼 것에 형광펜을 칩니다
판정이 아니라 순서예요.
- 05
사람이나 AI 가 읽고 판단해요
이 도구는 여기까지 안 옵니다.
한계도 여기서 나와요
GitHub 활동 기록은 90일, 300건까지만 남습니다. 그 밖으로 밀려나면 주소를 못 찾아요.
그래서 사고가 나면 빨리 봐야 하고, 도구도 이걸 화면에서 말해줍니다. 훑은 기록을 파일로 남기는 것도 같은 이유예요.

먼저 볼 것을 고르는 방식
넷 다 실제로 당한 공격에서 나왔어요. 여기 안 걸렸다고 괜찮다는 뜻이 아닙니다.
크기 급증
설정 파일 뒤에 공백을 길게 넣고 그 뒤에 코드를 숨기는 수법이 있어요. 이름은 그대로라 눈에 안 띄는데 크기는 정직하게 늘어납니다.
저장소 간 같은 파일
도구로 여러 저장소를 덮어쓰면 완전히 같은 내용이 여기저기 들어가요. 내용의 해시가 같으면 같은 파일입니다.
커밋 위조
author 이름과 날짜는 바꿀 수 있어요. 그런데 committer 날짜는 실제로 커밋이 만들어진 시각이라 어긋난 자국이 남습니다.
도구 흔적
자동화 도구는 작업용 임시 파일을 만들고, 그게 커밋에 안 섞이게 .gitignore 에 적어둬요. 그 줄이 그대로 지문입니다.