В этом посте мы изучим тему фальшивых звёзд GitHub, поделимся своей методикой их выявления и покажем, как самостоятельно провести такой анализ любых репозиториев.
Если вам неинтересна история, то можете сразу перейти к коду в конце статьи.
А если вам понравилась статья, перейдите в репозиторий Dagster и поставьте нам реальную звезду GitHub!
Зачем покупать звёзды на GitHub?
Звёзды GitHub — один из основных показателей одобрения сообществом в GitHub. На первый взгляд, это просто способ похвастаться, не имеющий больше объективности, чем «лайк» в Facebook или ретвит в Twitter. Однако они влияют на серьёзные решения с высокими ставками, в том числе на выбор проектов, которые будут использоваться корпорациями, на принятие решений о финансировании стартапов и на то, в какие компании будут приходить талантливые профессионалы.
Естественно, мы всегда призываем заинтересованных в проекте Dagster ставить звёзды репозиторию и отслеживаем его количество звёзд в GitHub наряду с другими проектами. Поэтому когда мы заметили несколько новых опенсорсных проектов, набравших за неделю сотни звёзд, нас это впечатлило. В некоторых случаях всё казалось слишком гладким, чтобы быть правдой, а паттерны были нарушены: какие-то совершенно новые репозитории подпрыгивали до нескольких сотен звёзд всего за пару дней, зачастую очень кстати перед новым релизом или другим серьёзным объявлением.
Мы точечно проверили некоторые из этих репозиториев и нашли подозрительные аккаунты, похожие на фальшивые.
Нетипичная аудитория GitHub. Обратите внимание на даты создания.
Нам стало любопытно, что в большинстве инструментов анализа звёзд GitHub и в статьях по этой теме не затрагивается проблема фальшивых звёзд.
Мы знали, что существуют сомнительные сервисы, предлагающие приобретать звёзды за деньги, поэтому создали репозиторий-пустышку (
frasermarlow/tap-bls
) и купили несколько звёзд. Благодаря этому мы выявили профиль фальшивых аккаунтов и провели тест с несколькими репозиториями через GitHub REST API (при помощи pygithub) и базу данных GitHub Archive.За один день мой репозиторий стал популярным (см. эпилог статьи)…
… но потом он оказался не единственным.
Начнём покупать звёзды…
Так где же покупают звёзды? Для этого не нужно заходить в dark web. Достаточно воспользоваться Google, существуют десятки сервисов.
Чтобы составить профиль фальшивого аккаунта GitHub, используемого этими сервисами, мы купили звёзды у следующих сервисов:
- Baddhi Shop — специалист в недорогой имитации практически всех влияющих на общественность метрик. Всего за $64 сервис отсыплет вам одну тысячу фальшивых звёзд GitHub.
- GitHub24 — сервис Möller und Ringauf GbR гораздо дороже, одна звезда обойдётся в €0,85.
К чести этих сервисов нужно сказать, что звёзды незамедлительно оказываются у вас в репозитории. GitHub24 «доставил» 100 звёзд за 48 часов. Это вызвало бы сильные подозрения в репозитории, который до этого момента имел только три звезды. Запрос к Baddhi Shop был побольше, мы заказали 500 звёзд, которые и прибыли в течение недели.
Надо сказать, что вы получаете то, за что платите. Месяцем спустя все 100 звёзд GitHub24 остались на месте, но сохранилось лишь три четверти фальшивых звёзд Baddhi Shop. Мы подозреваем, что остальные были вычищены командами службы безопасности GitHub.
Как можно выявить такие фальшивые звёзды?
Мы хотели разобраться, насколько серьёзна проблема фальшивых звёзд в GitHub. Чтобы добраться до самой сути, мы предложили специалисту по спаму и подделкам Алане Гласко изучить данные, начав с анализа данных публичных событий в базе данных GitHub Archive.
Есть искушение сформулировать это как классическую задачу машинного обучения: просто купи несколько фальшивых звёзд и обучи классификатор выявлению реальных и фальшивых звёзд. Однако у такого подхода есть множество проблем.
- Какие признаки? Спамеры — мошенники и активно избегают выявления, поэтому очевидные признаки для классификации (имя, биография и так далее) обычно обфусцированы.
- Своевременность меток. Чтобы избежать выявления, спамеры постоянно меняют свою тактику. Создание разметки данных может оказаться сложной задачей, и даже размеченные данные могут оказаться устаревшими к моменту повторного обучения модели.
При распознавании спама для выявления спамеров часто используются эвристики в сочетании с машинным обучением. В конечном итоге мы в основном использовали эвристики.
После покупки фальшивых звёзд GitHub мы заметили, что у них существуют две когорты:
- Очевидные фальшивки. Одна когорта не особо старается скрыть свои действия. Просто взглянув на их профили, понимаешь, что это ненастоящие аккаунты.
- Изощрённые фальшивки. Другая когорта была гораздо более изощрённой и создавала большой объём реально выглядящей активности, чтобы скрыть факт поддельности аккаунтов.
Мы создали для выявления каждой из когорт две отдельные эвристики.
Выявление очевидных фальшивок
В процессе исследования фальшивых звёзд мы выявили множество одноразовых профилей: фальшивых аккаунтов GitHub, созданных исключительно для того, чтобы поставить звезду одному-двум репозиториям GitHub. Их активность ограничивается одним днём (днём создания аккаунта, соответствующим дню отметки звездой целевого репозитория) и больше они ничего не делают.
Мы воспользовались GitHub API, чтобы собрать больше информации об этих аккаунтах, и выявили чёткий паттерн. Эти аккаунты характеризовались крайне ограниченной активностью:
- Созданы в 2022 году или позже
- Подписчиков <=1
- Подписок <= 1
- Публичных gist == 0
- Публичных репозиториев <=4
- Поля электронной почты, возможности найма, биографии, блога и имени в twitter пусты
- Время простановки звезды == дате создания аккаунта == дате обновления аккаунта
При помощи этой простой эвристики низкой активности на основании данных GitHub API мы можем выявить многие (но вряд ли все) подозреваемые фальшивые аккаунты, поставившие звезду одному и тому же множеству репозиториев.
Что общего у всех этих пользователей GitHub?
Выявление изощрённых фальшивок
Вторую когорту фальшивых аккаунтов идентифицировать было достаточно сложно. Они вели схожую с человеческой деятельность: имели фотографии в профилях, биографии и реалистичную активность контрибьюторов. Описанная выше простая эвристика не идентифицировала эти аккаунты как фальшивые, даже если мы знали, что они поставили звёзды из-за покупки в сервисе. Как можно выявить такие реалистичные, однако точно фальшивые аккаунты?
Кластеризация
В конечном итоге мы остановились на методике под названием кластеризация без учителя (unsupervised clustering). Мы хотели создать множество признаков для каждого аккаунта. Обычные пользователи должны быть достаточно рассредоточенными; то есть их признаки должны быть достаточно уникальны для них и они не должны принадлежать к крупным кластерам. С другой стороны, фальшивые пользователи будут иметь схожие признаки, а при визуализации создавать кластеры. Чтобы выявить фальшивых пользователей, мы просто проверим, являются ли они частью подозрительно выглядящего кластера.
Проще всего понять это на примере. Рассмотрим показатель «дата активности». Большинство пользователей в GitHub не имеют публичной активности каждый день. Если аккаунт использует GitHub несколько дней в месяц и эти дни точно такие же, как у другого аккаунта, и они имеют схожую активность в эти дни, то это признак того, что потенциально оба аккаунта управляются одним скриптом.
Чтобы получить представление о том, как это выглядит, мы можем составить график множества пользователей, поставивших звезду конкретному репозиторию по количеству дат активности, общих с другими пользователями (ось x) и общим количеством репозиториев, с которыми они взаимодействовали (ось y):
Вот пример того, как это выглядит для нашего репозитория-пустышки, имевшего почти 100% фальшивых звёзд:
График нашей эвристики для множества известных фальшивок — совпадение близко к 100%
А вот как выглядит график для репозитория Dagster, имеющего (насколько мы знаем) ноль фальшивых звёзд. Обратите внимание на крошечные жёлтые точки в нижнем левом углу, определяющие несколько ложноположительных аккаунтов (показатель ложноположительного срабатывания = 0,17%):
График нашей эвристики для репозитория dagster-io — почти 0% соответствий
И наконец, в качестве промежуточного примера мы можем изучить репозиторий опенсорсного проекта, имеющий большое количество предположительно фальшивых звёзд и реальные оценки. Кластеры фальшивых пользователей GitHub выделяются.
График нашей эвристики для репозитория, который мы подозреваем в жульничестве, выделены фальшивые звёзды.
Улучшаем кластеризацию
Хотя эта исходная методика была интересной, сама по себе она оказалась недостаточно хороша для выявления фальшивых пользователей с большой долей уверенности. Нам нужно было её усовершенствовать.
Изучив данные после этой первоначальной гипотезы, мы выявили ещё один паттерн. Хотя эти изощрённые фальшивые аккаунты действовали реалистичным образом, мы обнаружили, что все фальшивки склонны были взаимодействовать с общим для всех них небольшим множеством репозиториев. По сути, похоже было, что каждый фальшивый аккаунт добавляет звёзды подмножеству пересекающихся «подозрительных репозиториев».
К сожалению, мы не могли просто найти этот список репозиториев и закончить на этом, потому что спамеры постоянно выполняют ротацию новых множеств репозиториев, которым ставят звёзды. Однако мы можем использовать наши методики кластеризации без учителя, чтобы выявлять такие подозрительные репозитории автоматически. Тогда мы будем знать, какие аккаунты фальшивые, на основании того, взаимодействуют ли они с этими подозрительными репозиториями (и насколько активно).
В частности, вот как мы идентифицировали, является ли пользователь подозрительным:
- Для начала мы получали список всех пользователей, поставивших звезду репозиторию, который мы хотели проанализировать.
- Затем мы идентифицировали множество потенциально подозрительных репозиториев на основании высокой степени пересечения с другими пользователями в этом множестве. Помните, что поскольку эти пользователи уже изначально связаны тем, что поставили звезду одному и тому же репозиторию, может быть подозрительным, если они голосовали за большое количество пересекающихся дополнительных репозиториев. (Но это также просто может значить, что этот кластер репозиториев действительно интересен одному и тому же множеству пользователей, поэтому так важен описанный ниже дополнительный этап!)
- Наконец, мы искали аккаунты с относительно низкими уровнями активности, основная часть активности которых приходилась на множество выявленных выше подозрительных репозиториев, не имевшие дополнительной реалистично выглядящей активности. Это и были наши фальшивые аккаунты.
При тестировании этой эвристики на известных фальшивых звёздах нашего аккаунта-пустышки мы выяснили, что хотя она может быть вычислительно очень затратной, эвристика очень хорошо справляется с выявлением фальшивых аккаунтов и при этом чрезвычайно точна (точность 98% и отклик 85%). В реальном репозитории всё должно быть более запутанным, поэтому нам не терпелось это протестировать.
Результаты
Объединив эти две модели, мы можем получить более полную картину подозрительной активности в выбранном репозитории GitHub и отклик каждого из методов:
Простая эвристика (очевидные фальшивки, низкий отклик) |
Простая эвристика + кластеризация без учителя (очевидные и изощрённые фальшивки) |
|||
Репозиторий | Количество звёзд | Предполагаемые фальшивые звёзды | % предполагаемых фальшивых звёзд | % предполагаемых фальшивых звёзд, полученных в 2022 году или позже (см. сноску) |
okcash | 759 | 1 | 0.13% | 97% |
Simple-GPU | 787 | 159 | 20% | 87% |
Notifio | 841 | 97 | 12% | 76% |
Mage.ai | 3,629 | 533 | 15% | 30% |
Apache Airflow | 29,435 | 17 | 0.06% | 1.6% |
Ploomber | 3,002 | 6 | 0.2% | 1.5% |
Dagster | 6,538 | 8 | 0.12% | 1.5% |
Flyte | 3,154 | 1 | 0.03% | 1.1% |
Сноска: из-за затрат на выполнение вычислений анализ GitHub Archive, выполненный в BigQuery, был ограничен звёздами, полученными начиная с 1 января 2022 года. Для анализа при помощи GitHub Archive использовался чуть отличающийся способ выявления того же типа подозрительных аккаунтов с низкой активностью, обнаруженных при анализе GitHub API. Эти аккаунты были скомбинированы с дополнительными подозрительными аккаунтами, выявленными при помощи методики кластеризации, что дало нам общее количество подозрительных фальшивых звёзд.
Готовы попробовать сами?
Если вы хотите проанализировать другие репозитории Github при помощи этой логики, то полный проект Dagster и dbt в Github находится здесь. Простая эвристика реализована на Python, поэтому вам достаточно лишь аккаунта Github и токена доступа.
Метод кластеризации без учителя реализован как проект dbt, поэтому для его запуска понадобится аккаунт Google Cloud BigQuery. Стоит заметить, что для больших репозиториев его выполнение может быть достаточно затратным.
Заключение
Создание моделей для выявления фальшивых аккаунтов (или других видов спама) со стопроцентной точностью — сложная задача. Мы можем разработать методики с относительно высокой точностью и откликом, но они становятся вычислительно затратными. Более того, мир постоянно меняется и многие модели требуют постоянной подстройки. Иногда использование простой эвристики позволяет получить достаточно данных малой ценой, поэтому всегда следует помнить о всём спектре возможностей. И наконец, простое наличие у репозитория фальшивых звёзд необязательно значит, что владельцы их купили, потому что спамеры часто пытаются скрывать свои фальшивые аккаунты, ставя звёзды настоящим репозиториям.
Учитывая серьёзность ставок и простоту, с которой можно купить фальшивые звёзды GitHub, радостно видеть, что это явление распространено не так широко; это говорит в пользу ценностей сообщества разработчиков.
Однако возможность прокачки репозитория фальшивыми звёздами демонстрирует изъяны в механизмах доверия и безопасности GitHub, и некоторые проекты определённо использовали их. Мы поделились своими открытиями с командой GitHub, поэтому не удивляйтесь, если все обнаруженные в этом туториале фальшивые аккаунты пропадут в ближайшие месяцы (см. эпилог), а количество звёзд GitHub в этих репозиториях резко упадёт.
Эпилог...
Спустя 48 часов после публикации этой статьи один продавец фальшивых звёзд предпринял действия, чтобы замести свои следы. Он удалил большинство профилей, использованных для простановки звёзд нашему тестовому репозиторию. Количество аккаунтов, поставивших звёзды frasermarlow/tap-bls, снизилось с 240 известных фальшивых профилей до всего 130. Ниже представлен список всех профилей. Ссылки ведут на пользователей, всё ещё не заблокированных на 19 марта.
BaddhiShop
ncolliny | cboyermichael | pixeyik | cromerjasonm | richardhammes | keseld | rockdav | rmadysw | stridli | ohnwiy | artmayi | jackschmidt981 | vidrayk | nielvoyik | mngear | mmyduv | miegasa | essapsa | ankfru | rvests | ahnistyi | endalesa | thidup | raymondkart | alesge | uisusans | ahirumadushank | wolferhonda344 | amyiks | sahasad | techhsa | sulivannin | juwanhau | subhanburhan | adamphi | sleeyik | Markdiscor | powerherry | peyvira | potterstar | kanchansa | johnhenricyi | bhilliphels | wmrgino | Johnzc1 | BeniniLazlow | sugaringgcndy | Gajan777 | elijahjames143 | Wendy5345 | Kshiza | Waqar259 | kevin9967 | Gamers1235 | hndeep | jprecto | wisokyben | katongokaku | ahmed12580 | Mushymasa | duxiandy | joemattYI | mpalmervincen | peterholt878 | Hossain9889 | Jhon0000000 | frazier324 | sheldon62 | boka127 | hamilton190 | Johnauthor | mohomadzaad | rakesh092583 | NatashaWheeler | zamannahid | sultana702 | me09889054367125 | marleslabiseh6758 | jhonrobert564 | beattyedward2 | amoin2232 | tharakashehan | smithcawrting1 | Melvin172 | Yasiru77 | argenis53 | trever786 | Jayed56123 | Tim-Flake90 | Bensonthomas119 | Robert1390 | Johanpater | georgerovalez | itsjamescurt | Poiu33 | sinhajhon1990 | litnytani | Rljgh | AAdamsmith321 | Priyanka5726000 | stevensailer | RubelKhan1 | jenniferamber6881 | masonsebastian | paulcdevita | jonylees5917 | Faruk1434 | Newjob078 | viratkholidamn | allendarly | rafiahmedyio | cristinaperezsa | donnellydrjonatan | irfanzad | stewartreynor | JacobMaha | benten7862 | abi1988001 | leza7589 | james878768 | Beryallen | francescodeck1 | hubbardjose200 | Paucelaura | tyreljast12 | Sheikhking | irwinern31 | Jacoboram | Russon2 | Michealgate | jhonny119 | trantow123 | izaiahhickle02 | starshanto77 | sonaldtaylorson | rickeyv0101 | denesikalexander | rowlandwest123 | armstrongmarley1 |
GitHub24
Все аккаунты GitHub24, активные на 19 марта 2023 года.
CottarHay | marycerry | slima77 | donnamira | itsumanimiya | carol-rose | rene-on-fire | karolinle | rollingay | tsengbao | jody-road | shelia-em | tim-the-barrel-binder | Janthefisher | seen-nguyen | byvallone | suzieawesome | dennis-brady | wilcome-to | wondawillis | RazanurGardener | petrashining | ellis-in-wonderland | gilbertpatterson | black-spider-rain | SuikaiChao | tom-pabst | uncle-tom-rod | marlin-wizzard | ini-coder | mintolight | alexankey | geraldkailu | crispus-tuck | sheng-shen-su | TimmyChung | sherrelljava | veralera | mirandamog | danielbeliever | jessicaarellanou | suipeng-ma | AlexTheGreatDevOps | J4uan1ta | laurelrod | joeyjoneso | god-save-the-queen | huiwuam | cryptogirrl | ced-on | Beardslay | maur33n | StaticKathy | SandySunshineBeach | GrahamTom | charlierob | stufe9 | MoongirlX | girl-codingg | EiffelRalf | here-comes-sally | shinystar1 | Hop-Kins | niklas-schi | tomfurst | mingonai | CodeJalil | smith2g | alexcandyy | raysandra | the-number-is-42 | djingi | torstenja | marco-wa | dennishirsch | celestine-palm | hulkron | Ericcoss | mengchaoun | sunonai | Chen-Weij | michelehealth | linta-cat | dennistele | schultecrypto | wolverinata | lazylea | BradQL | the-tech-writer | hollyduo | myotisa | jameschungmai | ritajoin | Jens-Ebers | ron-g-it | lionkingsimba | Jemima-bg | bradlyAR | marcia-opcode | burgermax |