Анализ безопасности 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. Кроме того, следует обратить внимание на то, чтобы строки были полностью экранированы, а проверка данных требует реализации на стороне сервера, поскольку во многих случаях, похоже, мало что делается за пределами клиента.