Python

TL;DR

В январе 2019 года мы запустили инструмент, который эффективно находит уязвимости в Python-коде. Мы создали автоматизированную систему, в которой объединили алгоритмы анализа потока данных с новым ML-компонентом. Таким образом, наш инструмент находит гораздо больше уязвимостей, чем другие, традиционные инструменты. Запустив его в нескольких репозиториях с открытым исходным кодом, мы нашли и сообщили о 35 критических угрозах безопасности из списка OWASP Top Ten. На скриншоте показана одна из угроз:

Обнаруженный нами межсайтовый скриптинг

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


Самый распространенный метод анализа кода называется taint-анализ: он помогает обнаружить такие уязвимости, как межсайтовый скриптинг (XSS), внедрение SQL-кода (SQLi), обход каталога (PT), удаленное выполнение кода (RCE) и т. д. Мне кажется, что популярность taint-анализа связана с простотой его основной идеи: «чтобы сделать код безопасным, сначала нужно убедиться, что экранирование пользовательского ввода прошло успешно».

Возьмем для примера этот сверхсложный фрагмент кода:

from django.http import HttpResponse
def hello(request):
    name = request.GET.get("name")
    return HttpResponse("Hello " + name)

Здесь пользовательский ввод из HTTP-запроса попадает в имя переменной name, а затем в вызов django.http.HttpResponse.Поэтому, если я добавлю скрипт <script>evil_code</script, то evil_code начнет выполняться в браузере жертвы. Если вы все еще не поняли, как это работает, то вот неофициальное краткое описание этого метода.

При taint-анализе выделяют три категории объектов (переменных, вызовов функций и т. д.):

  1. Sources (источники)— содержат введенную пользователем информацию (например, request.GET.get(“name”));
  2. Sanitizers (санитайзеры) — обрабатывают небезопасную введенную пользователем информацию, превращают ее в безопасную (например, django.utils.html.escape());
  3. Sinks (накопители данных)— запускают уязвимость, если злоумышленнику удастся ввести данные (например, django.http.HttpResponse()).

Главная цель анализа—убедиться, что все введенные пользователем данные пройдут через санитайзеры на пути из источника в накопитель. Каждый поток данных, не прошедший через санитайзеры, считается потенциальной уязвимостью.


К сожалению, taint-анализ зависит от спецификации: списка всех источников, накопителей данных и санитайзеров. Чтобы вручную составить такую спецификацию, нужен ​​«эксперт по безопасности», который должен разбираться и в базе исходного кода проекта, и во всех используемых сторонних средах. В идеале «эксперт по безопасности» должен составить список всех источников, накопителей и санитайзеров, присутствующие в коде, и запустить инструмент taint-анализа. Довольно очевидно, что у этого подхода есть некоторые недостатки.

Во-первых, представьте, насколько сложно вручную собрать такую спецификацию: нужно просмотреть тонну документации и кода, как проекта, так и фреймворков. А теперь вспомните знаменитую цитату Ларри Уолла: «Лень и нетерпеливость — это истинные добродетели великого программиста», и почувствуйте жалость к бедняге, которому поручили такое задание.

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

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

В-четвертых, этот подход не масштабируется. Каждый проект и каждая инфраструктура уникальны: получившиеся спецификации безопасности не получится использовать повторно на 100%.

Эти четыре недостатка также означают, что в этом случае не получится эффективно использовать такой распространенный инструмент, как Code Review. Более того, консультантов по безопасности слишком мало, их не хватит на все проекты.


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

Очевидно, что разработанный нами подход устраняет первый, третий и четвертый недостаток. Но что насчет второго? Мы провели экспериментальный поиск ошибок. С помощью нашего инструмента (выложен в открытый доступ) мы изучили репозитории с открытым исходным кодом на GitHub. Мы специально выбирали веб-приложения, которые используются (или будут использоваться) множеством людей (в том числе, злоумышленниками).

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

  1. Межсайтовый скриптинг в mozilla/pontoon
  2. Внедрение SQL-кода в earthgecko/skyline
  3. Межсайтовый скриптинг в earthgecko/skyline
  4. Межсайтовый скриптинг в DataViva/dataviva-site
  5. Внедрение SQL-кода в DataViva/dataviva-site
  6. Внедрение SQL-кода в lmfdb/LMFDB
  7. Межсайтовый скриптинг в lmfdb/LMFDB
  8. Межсайтовый скриптинг в gestorpsi/gestorpsi
  9. Внедрение SQL-кода в sharadbhat/VideoHub
  10. Удаленное внедрение кода в UDST/urbansim
  11. Межсайтовый скриптинг в viaict/viaduct
  12. Межсайтовый скриптинг в MLTSHP/mltshp
  13. Межсайтовый скриптинг в kylewm/woodwind
  14. Межсайтовый скриптинг в kylewm/silo.pub
  15. Межсайтовый скриптинг в anyaudio/anyaudio-server
  16. Внедрение SQL-кода в MinnPost/election-night-api
  17. Обход каталога в mitre/multiscanner
  18. Внедрение SQL-кода в PadamSethia/shorty

Перевод статьи Victor Chibotaru: Meet the tool that automatically infers security vulnerabilities in Python code