Группа исследователей из Университета Турку (Финляндия) опубликовала результаты анализа пакетов в репозитории PyPI на предмет использования потенциально опасных конструкций, способных привести к появлению уязвимостей. В ходе анализа 197 тысяч пакетов выявлено 749 тысяч потенциальных проблем с безопасностью. В 46% пакетов присутствует как минимум одна подобная проблема. Среди наиболее часто встречающихся проблем выделяются недоработки, связанные с обработкой исключений и использованием возможностей, допускающей подстановку кода.
Из выявленных 749 тысяч проблем 442 тысячи (41%) помечены как незначительные, 227 тысяч (30%) как проблемы умеренной опасности и 80 тысяч (11%) как опасные. Некоторые пакеты выбиваются из общей массы и содержат тысячи проблем: например, в пакете PyGGI выявлено 2589 проблем, в основном связанных с применением конструкции “try-except-pass”, в пакете appengine-sdk найдено 2356 проблем. Большое число проблем также присутствует в пакетах genie.libs.ops, pbcore и genie.libs.parser.
Следует отметить, что результаты получены на основе проведения автоматизированного статического анализа, который не учитывает контекст применения тех или иных конструкций. Разработчик инструментария bandit, который использовался для сканирования кода, высказал мнение, что из-за достаточно высокого числа ложных срабатываний результаты проверки нельзя напрямую считать уязвимостями без проведения дополнительного ручного рецензирования каждой проблемы.
Например, анализатор считает проблемой с безопасностью применение ненадёжных генераторов случайных чисел и алгоритмов хэширования, таких как MD5, в то время, как в коде подобные алгоритмы могут использоваться для целей, не влияющих на безопасность. Анализатор также считает проблемой любую обработку внешних данных в небезопасных функциях, таких как pickle, yaml.load, subprocess и eval, но данное использование не обязательно сопряжено с появлением уязвимости и на деле применение указанных функций может быть реализовано без угрозы безопасности.
Среди проверок, использованных в исследовании:
- Использование потенциально небезопасных функций exec, mktemp, eval, mark_safe и т.п..
- Небезопасное выставление прав доступа для файлов.
- Присоединение сетевого сокета ко всем сетевым интерфейсам.
- Использование жёстко указанных в коде паролей и ключей.
- Использование предопределённого временного каталога.
- Использование pass и continue в обработчиках исключений catch-all-style;
- Запуск web-приложений на базе веб-фреймворка Flask с включённым отладочным режимом.
- Использование небезопасных методов десериализации данных.
- Использование хэш-функций MD2, MD4, MD5 и SHA1.
- Использование небезопасных шифров DES и режимов шифрования.
- Использование небезопасной реализации HTTPSConnection в некоторых версиях Python.
- Указание схемы file:// в urlopen.
- Использование генераторов псевдослучайных чисел при выполнении криптографических задач.
- Использование протокола Telnet.
- Использование небезопасных парсеров XML.
Дополнительно можно отметить, обнаружение в каталоге PyPI 8 вредоносных пакетов. Перед удалением проблемные пакеты успели загрузить более 30 тысяч раз. Для скрытия вредоносной активности и обхода предупреждений простых статических анализаторов в пакетах применялось кодирование блоков с кодом при помощи Base64 и организация из исполнения после декодирования через вызов eval.
В пакетах noblesse, genesisbot,
are, suffer, noblesse2 и noblessev2 выявлен код для перехвата номеров кредитных карт и паролей, сохранённых в браузерах Chrome и Edge, а также для передачи токенов учётных записей из приложения Discord и отправки данных о системе, включая скриншоты содержимого экрана. В пакетах pytagora и pytagora2 присутствовала возможность загрузки и выполнения стороннего исполняемого кода.