Этичные хакеры из Go Secure обнаружили ошибку в MySQL, угрожающую безопасности. Из-за неё клиенты AWS Web Application Firewall (WAF) остались незащищёнными от внедрения SQL. Ещё одна исследовательская группа дополнительно подтвердила, что это влияет на безопасность, и предоставила один из способов, как исправить эту ошибку. В 2013 году в презентации BlackHat под названием «Методы оптимизации и обфуксации SQL» Роберто Сальгадо представил несколько методов обхода для SQL-внедрения. Доклад включал методы для MySQL и MariaDB. В 2018 году хакеры из GoSecure пересмотрели эту презентацию и начали проводить тесты с MySQL и MariaDB. Они обнаружили, что ошибка экспоненциальной формы записи чисел, упомянутая в презентации Сальгадо, имела более широкие последствия. Оказывается, с её помощью можно добиться интересных вещей – интересных с точки взломщика. Эта ошибка позволяет синтаксису SQL оставаться рабочим, даже если он не должен быть таковым, что сбивает с толку средства защиты. Экспоненциальная форма записи чисел (далее экспоненциальная запись) и, в частности, функция «e», была интегрирована во многие языки программирования, включая SQL. Неясно, является ли это частью всех реализаций SQL, но это часть реализации MySQL/MariaDB. Вот пример экспоненциальной записи, интегрированной в SQL-запрос из той самой презентации Роберто Сальгадо 2013 года. Обозначение «e» будет проигнорировано, поскольку оно используется в недопустимом контексте: SELECT table_name FROM information_schema 1.e.tables Таким образом, предыдущий запрос будет вести себя так же, как: SELECT table_name FROM information_schema .tables С помощью пары тестов обнаружено, что после команды «1.e» можно использовать следующие символы: ( ) . , | & % * ^ / Чтобы проиллюстрировать проблему, авторы обзора привели пример набора данных: Чего можно достичь с помощью команды «1.e» и символов за ней: Приведённый выше запрос равен следующему запросу: Примечательно, что цифра или число в команде «1.e» значения не имеет. Между точкой и функцией «е» может быть любое число или любой набор цифр, но точка является обязательной (например, «1337.1337e» также работает).  AWS — продукт CloudFront, который можно комбинировать с AWS WAF с определенными правилами. Они помогают компаниям защитить свои веб-приложения от взлома. Однако во время взаимодействия авторы обнаружили, что правило «База данных SQL» в AWS WAF можно обойти с помощью ошибки, указанной выше. Простой запрос может показать, что WAF блокирует запрос с помощью известной команды 1′ или ′1′=′1: Если использовать экспоненциальную запись в этом простом запросе, получится следующее: Одного такого доказательства достаточно, чтобы объяснить, почему и как работает эта ошибка и продемонстрировать уязвимость безопасности для всех заинтересованных лиц. Сначала ошибку в MySQL и MariaDB проигнорировали, так как никто не увидел последствий. Это никак не влияло на данные и не позволило повышать права, пока не нашелся обход WAF. Теперь, когда есть уязвимость в безопасности, можно выяснить, почему появилась такая ошибка и из-за чего она так себя ведет. Во-первых, MySQL и MariaDB работают, находя признаки в запросе, такие как: числа, строки, комментарии, конец строки и т. д. Как только признак распознан, нужная функция анализирует его. Во-вторых, кусок рассматриваемого кода проверяет целые или вещественные числа, поскольку сначала работает этот сегмент: В-третьих, сегмент кода находит точку и попадает в функцию действительных чисел, и это тот сегмент, который нужен для понимания ошибки: В этот момент сегмент кода уже обработал цифры перед точкой и начинает обрабатывать все цифры после точки. Потом условие проверяет, является ли символ буквой «e» или «E» и переходит к следующему символу. Если следующий за «е» символ не является цифрой, состояние устанавливается в «MY_LEX_CHAR», а затем завершается оператором «break», который возвращается в начало варианта переключения. Наконец, следующим сегментом кода достигнут нужный оператор, и здесь признак полностью забывается и удаляется из запроса: Как видно из примера, оператор «MY_LEX_CHAR» идёт через оператор «MY_LEX_SKIP», потому что, как можно понять из комментария «Unknown or single char token» (то есть неизвестный признак или символ) MySQL просто не знает, что с этим делать в данный момент. В случае с оператором «MY_LEX_SKIP» всё завершается возвратом символа. Если символ не является закрывающей круглой скобкой - «)», то переходим к оператору «MY_LEX_START», который будет искать новый признак. В любом случае, даже если он заканчивается закрытой скобкой, всё равно признак не возвращается, а отбрасывается. Для исправления ошибки достаточно было бы прервать запрос, если признак неверен, вместо того, чтобы его пропустить. Когда MySQL или MariaDB находят начало признака с плавающей запятой и что за ним не идет цифра, они должен прервать запрос. Хакеры отправили исправление в проекты MySQL и MariaDB. В данном случае это не проблема безопасности в MySQL/MariaDB как таковая. Любой WAF или аналогичные продукты игнорируют запросы SQL, сформированные таким образом, поэтому уязвимы. Если запросы в неправильном формате, продукты безопасности не будут рассматривать их как действительный код SQL и просто проигнорируют. Поэтому представленное исправление должно увеличить шансы на быстрое решение. Позже хакеры решили оценить ModSecurity, популярный WAF для Apache и nginx. Он включает в себя библиотеку libinjection, на которую влияет представленная ошибка. Ниже демонстрация возможности modsecurity блокировать вредоносный шаблон для SQL-внедрения. Возвращается запрещённая страница, что является следствием обнаружения. Записи из modsecurity, в которых подчеркивается, что библиотека libinjection была запущена: Обойти эту защиту можно, поставив перед буквальным выражением экспоненциальную запись «1.e». Библиотека Libinjection маркирует этот признак и определяет типы контекстных разделов как в предыдущем случае: комментарии и строки. Libinjection рассматривает строку «1.e» как неизвестную команду SQL и приходит к выводу, что это скорее часть текста, чем часть кода. Такое поведение библиотеки libinjection возможно, когда она встречает неизвестную функции SQL. OWASP Core Rule Set (CRS) указали, что эффективная защита доступна ModSecurity, если установлен уровень в классификации ModSecurity «paranoia level 2». В нём есть функционал к обнаружению скрытых атак. Эта проблема безопасности не похожа на многие другие, так как она может быть легко преуменьшена до простой ошибки синтаксического анализатора. AWS понял риск и решил исправить это в своём WAF, тем более, что это ситуация оставляла клиентов Amazon незащищёнными. Есть надежда, что в перспективе MySQL и MariaDB исправят ошибку, и через десяток лет метод исправления, показанный в данной статье, не понадобится. Информационная служба Хабра