Education

StackOverflow стал спасением для многих программистов, включая меня. Некоторые из нас никогда не посещали домашнюю страницу StackOverflow. Единственный способ, по которому мы попадали на сайт, — это когда искали в Google решение для нашей проблемы или ошибки.

Это удобная привычка, но так мы можем невольно начать использовать код, содержащий ужасные ошибки или изъяны безопасности. Даже если все понимают, что копипаст кода со StackOverflow, — плохая идея, разработчики все равно поступают так.

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

Вы можете подумать, что этот страх насчет безопасности, — городская легенда. Могу вас заверить: это не так.

Недавно я столкнулся с несколькими инцидентами, которые привлекли мое внимание, и я кратко расскажу о каждом из них.

Разработчик-копипастер: “Ctrl+C & Crtl+V. Коммит. Готово!”

Наиболее часто копируемый сниппет кода Java со StackOverflow содержит изъян!

Я впервые натолкнулся на это, читая один блог. Эта конкретная статья в блоге была написана самим автором кода. Вы можете прочитать ее здесь.

Автор кода, Андреас Лундблад, Java-разработчик в Palantir и один из самых высокопоставленных участников StackOverflow, признал этот изъян.

В исследовательской статье Себастьяна Балтеса, опубликованной в 2018 году в журнале “Empirical Software Engineering”, сниппет кода Андреаса, размещенный на сайте, был идентифицирован как Java-код, который интенсивнее всего копируют со StackOverflow и затем повторно используют в проектах с открытым исходным кодом. Этот сниппет был скопирован и внедрен в более чем 6000 Java-проектов на Github.

Данный сниппет кода был предоставлен в качестве ответа на этот вопрос, опубликованный на StackOverflow в 2010 году. Его функция заключается в преобразовании количества байтов в более удобочитаемый формат. Например, он преобразует 1024 байта в 1 кб или 104 8576 байтов в 1 МБ.

Получив от Себастьяна Балтеса информацию о таком заметном распространении его сниппета кода, Андреас перепроверил код и опубликовал исправленную версию у себя в блоге.

В конце своей статьи Андреас изложил несколько ценных советов для разработчиков:

  • Сниппеты со StackOverflow могут содержать баги, даже если имеют тысячи голосов “за”.
  • Проверяйте все граничные значения, особенно для кода, скопированного со StackOverflow.
  • Обязательно включайте правильную атрибуцию при копировании кода. Кто-то может указать вам на это.

Пускай этот баг — тривиальный граничный случай, и вызывал бы только неточности в оценке размера файла, всё могло бы быть и гораздо хуже. Давайте взглянем еще на несколько примеров.

Основные изъяны безопасности в самых популярных фрагментах кода C++ на StackOverflow

Исследовательская работа, опубликованная в 2019 году Morteza Verdi et al, показала, что шестьдесят девять самых популярных сниппетов кода C++, опубликованных на StackOverflow за последние десять лет, содержат серьезные изъяны безопасности.

Эти 69 наиболее уязвимых сниппетов кода используются в 2589 проектах на GitHub. Наиболее распространенной уязвимостью, распространяемой со StackOverflow на GitHub, по мнению исследователей, является CWE150:

CWE — это разработанный сообществом список распространенных недостатков безопасности программного и аппаратного обеспечения. Он служит общим языком, мерилом для инструментов безопасности и основой для выявления слабых мест, смягчения последствий и их предотвращения.

CWE150 — это ситуация, в которой происходит неправильная нейтрализация пространства, мета-пространства или пространства управления.

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

Вы не можете одновременно запустить Docker для Windows и Razer Synapse Driver Management Tool, так как они содержат ошибку со StackOverflow

Два года назад возникла странная проблема с Docker для Windows. Люди не могли запустить Docker на своих компьютерах с Windows. Эта странная проблема была отмечена одним пользователем в Github, и несколько других пользователей сообщили, что они также столкнулись с ней. Никто не знал, что же на самом деле не так, пока не появился этот пост на Reddit.

Было установлено, что проблема возникает при попытке запустить Docker для Windows, в то время как в фоновом режиме уже работает Razor Synapse. Если у вас запущен Razer Synapse, Docker думает, что уже запущен экземпляр собственной программы, и не запустится.

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

var name = string.Format("Global\{0}", (object) Assembly.GetExecutingAssembly().GetType().GUID);

Проблема в том, что возвращаемый идентификатор GUID является идентификатором GUID для типа System.Reflection.RuntimeAssembly, а не GUID для типа, определенного в сборке Docker для Windows.

Кое-что интересное

Если бы только одно из приложений использовало приведенный выше неправильный сниппет кода, то проблемы не возникло бы. Но, как оказалось, оба приложения использовали неверный сниппет кода, тем самым не позволяя обоим экземплярам работать одновременно.

Как вы думаете, откуда эти два приложения получили этот самый сниппет кода?

Вы уже догадались — StackOverflow.

Вот ошибочный пост со StackOverflow, ставший источником кода для обоих приложений: https://stackoverflow.com/questions/502303/how-do-i-programmatically-get-the-guid-of-an-application-in-net2-0.

Вы не увидите ошибочный ответ, если посетите страницу сейчас, так как он был отредактирован. Если вы хотите увидеть его своими глазами, посетите архивную версию страницы с помощью Wayback Machine.

Ключевые выводы для разработчиков от Foone Turing:

  • Подумайте о том, как бы вы нашли эту ошибку в своих собственных программах.
  • Вы копируете и вставляете код, и он, кажется, работает. Чего вы не понимаете, так это того, что он испорчен, потому что вы не запускаете ни одну из программ, в которых допущена та же ошибка.

Следует ли мне избегать копирования?

Не совсем

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

“Если вы заимствуете вещи и не понимаете содержания того, что заимствуете, то вы попадаете в ловушку повторного использования кода, который имеет потенциальные уязвимости. Тогда вы просто распространяете их вокруг себя.
Если вы собираетесь повторно использовать код, вам нужно понять этот код”, — Райан Донован.

Счастливого кодирования!

Читайте также:


Перевод статьи Mahdhi Rezvi: “Why Code Snippets From Stack Overflow Can Break Your Project”

Предыдущая статьяПроверка типов в Python
Следующая статьяКак комментировать файлы JSON