GitHub의 심각한 가짜 참여 문제: API를 통해 확인한 충격적인 실태
GitHub has a serious fake engagement problem and I wanted to see how visible it actually is through the public API, its worse than I thought after I went down that rabbit hole...
핵심 요약
GitHub의 가짜 별점 문제를 탐지하고 분석하는 도구 'phantomstars'를 개발하여 그 실태를 폭로함.
- 가짜 참여 탐지 — GitHub Trending의 급격한 별점 상승 저장소를 추적하여 봇 활동을 식별함.
- 분석 모델 적용 — 계정 생성일, 프로필 완성도, 활동 이력을 가중치로 계산해 봇을 분류함.
- 자동 알림 시스템 — 가짜 참여 비율이 높은 저장소에 직접 이슈를 생성해 유지보수자에게 경고함.
- 오픈 소스 공개 — 탐지 데이터와 분석 도구를 공개하여 AI 관련 쓰레기 콘텐츠 확산을 방지함.
확인해 보니 아주 잘 보였습니다. 어제 스캔 결과, 단일 저장소의 참여자 185명 전원이 봇으로 확인되었습니다. 90%도, "대부분 의심스러운" 수준도 아닙니다. 단 한 명도 빠짐없이 전부 봇이었습니다. 해당 저장소에는 실제 사용자가 누른 별점이 하나도 없었습니다.
제가 만든 것
phantomstars는 GitHub Actions를 통해 매일 실행되는 파이썬 도구입니다(무료, 서버 불필요):
- GitHub Trending을 스크랩하고 지난 7일간 생성된 저장소 중 별점이 급격히 상승한 곳을 검색합니다.
- 저장소별로 지난 24시간 동안의 별점 및 포크 이벤트를 가져옵니다.
- GraphQL API를 통해 모든 참여자의 프로필(계정 생성일, 팔로워 수, 저장소 기록)을 일괄 조회합니다.
- 계정 생성일(35%), 프로필 완성도(30%), 저장소 패턴(25%), 활동 이력(10%)의 가중치 모델을 사용하여 각 계정의 점수를 매깁니다.
- 타임스탬프 클러스터링과 유니온 파인드(union-find)를 사용하여 조직적인 캠페인을 탐지합니다: 3시간 이내에 참여한 4명 이상의 의심스러운 계정 그룹을 식별합니다.
- 타겟 저장소에 직접 이슈를 생성하여 유지보수자가 상황을 알 수 있게 합니다.
캠페인 ID는 정렬된 멤버 세트의 결정론적 SHA-256 지문이므로, 동일한 봇 그룹은 실행 시마다 동일한 ID를 갖게 됩니다. 개별 계정이 정지되더라도 며칠에 걸쳐 봇 팜(farm)을 추적할 수 있습니다.
실제 패턴의 모습
매우 일관적입니다. 원시 데이터에서 나타나는 가짜 참여 캠페인의 특징은 다음과 같습니다:
- 40~200개의 계정이 모두 동일한 1~2주 기간 내에 생성됨
- 원본 저장소가 없거나, 전혀 건드리지 않은 포크만 존재함
- 자기소개, 위치, 팔로워, 팔로잉이 없음
- 모두 90분 이내에 동일한 저장소에 별점을 남김
- 타겟 저장소는 보통 도구, 해킹, 실행기(executor), 생성기임을 암시하는 이름을 가짐
오늘 스캔 결과: 3,560개의 프로필 계정에 걸쳐 53개의 활성 캠페인이 발견되었습니다. 798개가 likely_fake(가짜일 가능성 높음)로 분류되었습니다. 타겟이 되는 저장소들은 대부분 신뢰도를 빠르게 조작해야 하는 저품질 AI 도구와 "실행기" 소프트웨어였습니다.
영향을 받는 저장소 알림
저장소의 가짜 참여 비율이 40%를 넘거나 캠페인이 탐지되면, phantomstars는 해당 저장소에 계정 로그인, 생성일, 종합 점수, 캠페인 멤버십 등이 포함된 전체 의심 목록을 이슈로 생성합니다. 유지보수자는 이 프로젝트를 먼저 찾을 필요 없이 자신의 이슈 트래커에서 바로 확인할 수 있습니다.
참고로, 이러한 저장소 중 상당수는 이슈 기능을 비활성화해 두었는데, 이는 그 자체로 위험 신호입니다. 그런 저장소는 조용히 건너뜁니다.
이 도구를 만든 이유
별점은 개발자가 무엇을 평가하고, 무엇에 의존하며, 무엇을 추천할지 결정하는 기준입니다. 이 신호가 돈으로 매수되면, 그 영향은 실제 의사결정까지 이어집니다. 이 문제는 얼마나 측정 가능한지 궁금해서 시작했는데, 예상보다 훨씬 더 잘 측정되었습니다.

