Анализ безопасности OpenTrade

Группа компаний Arcadia при сотрудничестве с Evimeria

Первоначальное открытие: Минь Кхай До и Джоэл Фаррис

Автор: Бен Хейворд

Предисловие

В этом документе описывается ряд уязвимостей и слабых мест, обнаруженных в системе OpenTrade компанией 3s3s. Сначала была проведена ручная проверка кода для выявления явных слабых мест, а затем был использован ряд инструментов статического анализа и тестирования на проникновение для расширения поиска. Предлагаются советы по передовому опыту, а также все данные испытаний.

Оборудование, используемое в этом тесте, представляло собой один небольшой экземпляр EC2 на Amazon Web Services (AWS), работающий под управлением Ubuntu 16.4 LTS. Были открыты порты, чтобы разрешить весь доступ только к основной лаборатории, работающей под управлением Manjaro 18.0.2, а сертификаты TLS на машине были созданы вручную и самоподписаны.

Проверка кода

Проверка и дезинфекция данных:

В некоторых местах в системе есть слабые места в проверке и дезинфекции данных. Например, когда пользователь входит в систему, данные не проходят тщательную проверку. Он проверяется на стороне клиента в static_pages / js / login.js, проверяя, равен ли пользователь нулю, и запрос аутентификации отправляется на сервер через SSL. При получении выполняется единственная проверка на стороне сервера - это проверка того, что имя пользователя и пароль действительно были переданы. Лучше всего тщательно проверять данные, которые вы ожидаете на стороне сервера.

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

Пример проверки на стороне клиента

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

Если вы хотите избежать использования сторонней библиотеки, для проверки можно использовать регулярное выражение, например для пароля, что-то вроде:

“^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$”

Определение регулярного выражения для поля с минимум 8 символов,

1 заглавная буква, 1 строчная буква, 1 символ и цифра

В качестве альтернативы можно использовать стороннюю библиотеку, такую ​​как express-sanitizer или express-validator, чтобы позаботиться о работе, в зависимости от ваших предпочтений.

Данные также не всегда экранируются до того, как они будут использованы на стороне сервера, что открывает множество векторов межсайтового скриптинга (XSS) для атак, таких как SQL-инъекции, что ставит под угрозу безопасность базы данных. Это еще одна проблема, которую можно решить с помощью библиотеки, например экспресс-валидатора.

Пример отсутствия проверки и очистки данных (static_pages / js / login.js)

Пользователи, созданные из номера строки SQL:

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

g_constants.dbTables['users']
    .selectAll('ROWID AS id, *', 'login="'+escape(user)
    +'" AND email="'+escape(email)+'"', '', (err, rows) => {

Статический анализ:

ZAProxy:

При тестировании с использованием OWASP ZAProxy вернул несколько проблем, только одно - средней степени серьезности, остальные - низкого уровня. Это можно увидеть в следующей таблице. Полные данные CSV также доступны по адресу:

Https://cloudflare-ipfs.com/ipfs/QmZ8Zz1wKZnLeRmCdi9WjfPufuFsV5Li8LsG739XAdnQkW

Резервное копирование: https://drive.google.com/file/d/1JR8O9yU-M04_1xD1Jz9vL1y2ChuaGsNW/view?usp=sharing

Для заголовка X-Content-Type-Options заголовка Anti-MIME-Sniffing не задано значение «nosniff». Это позволяет более старым версиям Internet Explorer и Chrome выполнять MIME-сниффинг тела ответа, потенциально вызывая интерпретацию и отображение тела ответа как тип контента, отличный от объявленного типа контента. Текущая (начало 2014 г.) и предыдущая версии Firefox будут использовать объявленный тип содержимого (если он установлен) вместо выполнения MIME-сниффинга.

LGTM:

Кроме того, был проведен статический анализ с использованием LGTM, который выявил

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

Https://lgtm.com/projects/g/3s3s/opentrade/alerts/?mode=list

Сводка уязвимостей и ошибок:

Проверка зависимости OWASP:

Зависимости для OpenTrade немногочисленны, но для полноты картины имеет смысл проверить, что никакие зависимости не имеют публично известных уязвимостей. Как и ожидалось, получился чистый лист, который можно увидеть ниже:

Https://cloudflare-ipfs.com/ipfs/QmdXbC6DRKCRQvgswQwEhaTd2z2CmwHcdJqEp728V8XpFD

Это было протестировано во второй раз с использованием retire.js, который вернул тот же чистый лист.

Другие вопросы:

Другие несвязанные проблемы, которые не находятся строго в кодовой базе, включают рекомендуемую версию узла 8.0.0 - это, вероятно, плохой совет, и вам лучше всего проинформировать пользователей, чтобы они оставались в ветви LTS узла, например v8.9.0 - Поскольку предлагается долгосрочная поддержка, это гораздо более безопасная альтернатива для производственных систем.

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

Заключение:

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

Еще одна ключевая область - установить заголовок X-Frame-Options, чтобы уменьшить вероятность того, что пользователь будет перехвачен кликом, это должно быть выполнено с уже импортированным пакетом cors. Кроме того, следует обратить внимание на то, чтобы строки были полностью экранированы, а проверка данных требует реализации на стороне сервера, поскольку во многих случаях, похоже, мало что делается за пределами клиента.