История взлома одного WordPress плагина — или о том, как вы допускаете уязвимости в своих проектах

Оригинал поста на хабре

Давным давно, когда я был молод и писал сайты на PHP, я написал SEO плагин для маскировки внешних ссылок для Wordpress. Поскольку с воображением у меня плохо, то назвал его WP-NoExternalLinks. За всю историю у него было 360.000 установок и, кажется, до 50.000 активных установок.

Дальше я расскажу, каким именно образом он попал в недобросовестные руки и был злонамеренно использован - но для этого придётся немного погрузиться в его историю и обстановку разработки. Сразу предупрежу, что эта история абсолютно реальная.

История

Только на первый взгляд кажется, что задача плагина элементарна - на самом деле, нужно было реализовывать кучу различных вариантов маскировки, заботиться, чтобы это работало с кэширующими плагинами, не конфликтовало с другими парсерами контента, любыми структурами пермалинков, каждой новой версией Wordpress, и так далее. Около 8 лет я поддерживал этот плагин, отвечал на баг репорты и порой отлаживал чужие сайты, доверчивые владельцы которых добровольно выдавали мне все пароли и явки.

В какой-то момент мне стало понятно, что свои задачи я плагином не решаю уже много лет, поддерживать его код мне неинтересно, а больше ничего от его разработки я не получаю. Для справки уточню, что в описании и на страничке настроек плагина были ненавязчивые ссылки и кнопки с предложением сделать добровольное пожертвование - но за всю историю плагина мне пришло в районе 40$. Так что денежной мотивации не было, мотивации к развитию тоже, да и как-то порядком надоело, что каждый пользователь почему-то считает, что ты ему обязан, раз он таки поставил твою программу или плагин (кажется, многие пользователи действительно считают, что как только они ставят программу, какой-то добрый облачный дух выдаёт её разработчику мешок денег).

Это я не к тому, что мир несправедлив, и я лил горькие слёзы обиды - просто чтобы было понятно, что несколько лет я поддерживал этот плагин исключительно из странного ощущения, что пользователи мне доверились, и я не могу их обмануть и прекратить поддержку. Когда я оглядываюсь на эти ощущения сейчас, то понимаю, что это было глупое ощущение, и нужно было спокойно похоронить плагин и заниматься своими делами. Но это ощущения меня из 2018 года - с появлением двух детей довольно сильно меняются приоритеты.

Продажа

И вот в какой-то момент пришёл некий гражданин, который мне предложил неплохую сумму денег за приобретение плагина. Честно говоря, я был уверен, что это какое-то кидалово, и общался с ним исключительно из любопытства (ну, как со всякими нигерийскими принцами). Скепсис ушёл, когда мы договорились использовать один доверенный сервис для подобного рода сделок. Тут уже стало интересно - было ощущение, что мне заплатят, но я подозревал, что в плагине быстро появится какая-то уязвимость, и поэтому специально подготовил письмо в команду поддержки wordpress, чтобы моментально заблокировать плагин. Но тому времени я уже почти поверил, что плагин действительно хотят приобрести для расширения портфолио компании, которая занимается SEO оптимизацией (именно такой мотивацией мне это объяснили).

И знаете, что произошло дальше? Дальше мне честно пришли перечисленные деньги, и через несколько дней в плагин пришло мажорное обновление, в котором полностью изменился интерфейс и была переработана кодовая база (но оставлена совместимость) - так что это больше стало похоже на код из 2017, а не 2010 года (над этим поработал разработчик, как минимум, Middle уровня). Я был страшно рад - я нашёл заинтересованных людей, которые будут поддерживать мою игрушку, и которые уже принесли в неё много хорошего, радуя пользователей плагина.

Тем не менее, я в течении двух недель отсматривал код плагина и его обновления, на всякий случай держа палец на отправке письма в команду wordpress. Но всё было отлично и я успокоился.

Уязвимость

Хотелось бы остановиться на этом месте и закончить это как success story, но увы. Через несколько месяцев со мной связались ребята из стороннего проекта по безопасности wordpress, и рассказали, что в плагине появился бекдор, и им интересны подробности того, как я передал права на него новому разработчику. Проверив, я убедился, что плагин действительно заблокирован на сайте wordpress. Дальше я переписывался с поддержкой wordpress, краткие результаты такие:
  • Они приняли от меня всю информацию, которая может помочь в инциденте;
  • Они очень долго не хотели рассказать мне информацию о уязвимости, и пришлось искать её самому;
  • Моё желание помочь было осмеяно, и меня ругали всякими плохими словами за то, что я “продал плагин спамеру” и “нагрузил их работой” (дословные цитаты);
  • Через некоторое время сотрудники wordpress таки сами исправили закладку и отослали мне на ревью (хоть один позитивный момент);
  • Плагин так и останется заблокированным, и передавать обратно права на него они не будут.
Кстати, закладка оказалась отнюдь не злобным бекдором, а просто добавляла немного SEO ссылок ничего не подозревающим пользователям. Неприятно, но не так фатально, как могло бы быть.

По итогам общения:

  • Было потрачено много времени для устранения уязвимости из-за нежелания сотрудничать со стороны техподдержки wordpress
  • Wordpress навсегда потерял один из плагинов и разработчика, который больше не будет там ничего публиковать и обновлять. Вряд ли кто-то будет об этом сожалеть, но тем не менее.

UPD. По просьбам тех, у кого стоит плагин - “закладка” есть в версиях плагина 4.2.0 - 4.2.2. Версия 4.3 была исправлена поддержкой wordpress, версии до 4.0 были мои, а в версиях 4.0.0 - 4.1.0 “закладку” ещё не добавили. Скорее всего, ваш блог уже сам обновил плагин до безопасной версии 4.3.

Выводы

Для меня самыми интересным стали вопросы “продал бы я этот плагин, если бы знал, что его будут злонамеренно использовать?” и “сделаю ли я это снова, если будет возможность?”. С одной стороны - хотелось бы верить, что нет. С другой стороны - по сути у меня есть выбор между “хранить лояльность людям, которые даже не сказали спасибо за использование результатов моего труда” или “поехать с детьми в отпуск на море”. Ну… Не знаю. Искушение серьёзное.

Можно говорить о том, что здесь для меня есть какие-то репутационные риски, но… Я не являюсь какой-то компанией, которую можно опозорить по всему интернету. И я не являюсь иконой мира разработки, я всего лишь один из миллионов разработчиков, которые периодически что-то пишут в open source. И скажем честно - нельзя потерять репутацию, которой нет. Удивительно, что после продажи плагина хоть один ресурс связал с ним моё имя. Так что - никаких репутационных ирисок.

Отдельно замечу, что, в случае, когда риски касаются моей коммерческой деятельности, то здесь картинка совсем другая. На моей работе мне платят деньги, и у меня есть определённые обязательства. Неоднократно мне приходили различные предложения сомнительного характера, и я не принял ни одного - даже когда знал, что моё вмешательство или передачу данных никак не смогут отследить. Перед коммерческими проектами совершенно другая степень ответственности - и, как ни странно, не только потому, что мне там платят деньги, и потому что я там подписывал 100500 всяких бумажек. В первую очередь я чувствую ответственность потому что меня там ценят, доверяют, и это показывают. Поэтому я не могу предать оказываемое доверие. А, возвращаясь к open source… Тут картинка совсем другая. К примеру, помимо плагинов у меня есть ещё мобильные приложения. Они поддерживаются на нескольких ресурсах, в том числе на 4pda. И обычно пользователь (у меня их несколько тысяч) заходит туда, чтобы оставить сообщение вида “какашка не работает” (дословная цитата). Ну… Когда мне после этого приходит пулл реквест с обновлением бинарника из зависимостей приложения, то мне очень сложно не забить на него или не принять его вслепую, а вместо этого пересобрать его заново своими руками и выложить новый релиз.

Помните - никто вам ничего не должен

Повторюсь - моя цель - не пожаловаться на то, как всё плохо, а просто напомнить вам, что в open source никто ничего никому не должен. И нужно заботиться о безопасности любых сторонних компонентов, которые вы используете. Начиная с физического сервера, где крутятся ваши проекты (если он у вас “по знакомству”, то возможно всякое), продолжая фронтовыми и бэковыми компонентами, плагинами, фреймворками, CMS и так далее. И все проблемы в мире не решаются “вводом данных карточки в iframe”, как предлагалось в одной недавней статье.

Что же делать

Что вы можете помимо того, что следить за своей безопасностью? Как минимум, вы можете более ответственно относиться к тому, что вы используете труд других разработчиков. Посмотрите, что вы сейчас активно используйте. Купите лицензию для сломанного ещё два года назад вебшторма. Оплатите хитро полученный шаблон, которые вы использовали в большом заказе. Настройте автоматическое списание в пользу разработчиков вебпака. Перестаньте уже в каждом посте PVS Studio писать о том, как вы героически удаляете комментарии из своего кода, чтобы использовать этот инструмент бесплатно. Пожертвуйте уже 5$ разработчику Android KeePass - он об этом просит только по большим праздникам.

Если нет денег - зайдите в issues и расскажите о проблеме, или отправьте свой пулл реквест. Вспомните ошибку, которая у вас возникает в экзотических условиях, повторите её и опишите разработчику. Сделайте пулл реквест из вашего форка, в котором вы исправили какой-то баг, и это исправление так и осталось только у вас.

Если у вас нет ни денег, ни возможности участвовать в разработке - просто зайдите и скажите “спасибо” разработчику. Этим, как известно, сыт не будешь - но даже это радует разработчика и порой является стимулом для продолжения работы. Удивительно, что в устном общении принято благодарить за то, что для тебя делают - но этого правило так редко применяется в open source разработке.

Кстати, эти правила относятся не только к разработке. Так же можно взять за правило - понравилась прочитанная с торрентов книга - купи её. Нравится музыка - поучаствуй в краудфанде нового альбома. Вроде бы это так просто, но мало кто это делает. Давайте помогать друг другу, и мир станет лучше. И безопаснее.

А касательно того, что вы можете сделать, будучи разработчиком - сразу думайте, как обеспечивать поддержку вашего проекта. Может быть, вы сможете придумать, как привлечь к этому других разработчиков. Или предлагать дополнительные услуги - например, поддержку и отладку за некую фиксированную цену, или Enterprise решения, основанные на вашем проекте. Например, если бы я брал хотя бы по 10$ за поддержку плагина на сайтах пользователей, то, возможно, у меня был бы неплохой доход, который позволил бы не продавать плагин и дальше заниматься его разработкой. Многие считают монетизацию проекта чем-то плохим и изначально дурнопахнущим, но конце концов только она позволяет посвящать проекту достаточно много времени и заботиться о его качестве.

Прошу прощения, что столько вашего времени потратил на прочтение совершенно очевидных вещей - просто опыт показывает, что их очевидность никак не влияет на их применение. И этот случай с плагином заставил меня о многом подумать. Надеюсь, вам тоже было интересно и полезно.