Предисловие

В своей работе мы используем MariaDB и ранее никаких проблем с ее работой не было.

Утро админов

Нет ничего лучше с утра в понедельник, чем чашечка бодрящего кофе крик программиста – "у нас на локалке не импортируется база с продакшена!" Это реально бодрит. Грешным делом даже подумал – не вирусы ли нам подкинули? Учитывая что на локальной машине среда развернута точно такая же, что и на продакшене... Ну, почти такая же...

Это че такое?

Расследование

Первая строка дампа SQL содержала очень странную строку:

/*!999999\- enable the sandbox mode */ 
-- MariaDB dump 10.19  Distrib 10.11.8-MariaDB, for Linux (x86_64)
--
-- Host: localhost    Database: test.ru
-- ------------------------------------------------------
-- Server version       10.11.8-MariaDB

Да ладно? Это что такое? Что за sandbox mode?

Сравнил версии базы данных на сервере и на локалке.

На сервере
mariadb Ver 15.1 Distrib 10.11.8-MariaDB, for Linux (x86_64) using EditLine wrapper

На локальном компьютере:
mariadb Ver 15.1 Distrib 10.11.7-MariaDB, for Linux (x86_64) using EditLine wrapper

Ну не могли же в минорной версии поломать совместимость экспорта и импорта?

Пришлось изучать интернет в поисках ответа и даже грешным делом спрашивать chatGPT. chatGPT сморозил чушь, которую даже не хочется приводить. В общем-то не удивительно – за новостями он особо не следит....

В интернете тоже сразу не удалось толком ничего нагуглить (и даже наяндексить). Пошел читать новости на сайте MariadDB.

Вау! А вот и новость от 17 мая 2024 года, которая все объясняет – https://mariadb.org/mariadb-dump-file-compatibility-change/

Кому лень читать – да, мы поломали совместимость с предыдущими версиями MariaDB а так же с MySQL при импорте и экспорте SQL дампов и теперь придется удалять первую строку из файла, созданного mysqldump (mariadb-dump), если хотите чтобы работало как раньше.

Зачем, почему и как так вышло – разберемся далее в статье. А сейчас пока голые факты и рецепты.

Изменения коснулись версий MariaDB 10.5.25, 10.6.18, 10.11.8, 11.0.6, 11.1.5, 11.2.4 and 11.4.2. Начиная с этих версий в mysqldump (mariadb-dump) появляется злополучная строка, которая при импорте в старых версиях mariadb (и всех версиях mysql) приводит к ошибке импорта ERROR at line 1: Unknown command "-" . Удаление этой строки позволяет произвести импорт как раньше.

Рецепты удаления первой строки из дампа mysqldump (mariadb-dump)

Сразу приведу рецепты удаления первой строки, которые приведены по ссылке и добавлю еще один из комментариев:

Рецепт 1:

Можно удалить первую строку во время экспорта так:

mariadb-dump | tail +2

Рецепт 2:

Можно удалить первую строку во время импорта так:

tail +2 | mariadb

Рецепт 3 (из коментов):

Мне этот рецепт показался наиболее универсальным, потому что подходит для любых дампов – тех, которые содержат первую строку c sandbox mode и тех, которые ее не содержат.

sed -i '1{/999999.*sandbox/d}' yourfile.sql

А что случилось-то?

С чего вообще начался сыр-бор? По ссылке в статье описано как-то все мутно и невнятно. То есть закрываем какую то уязвимость и как можно скорее.... Пришлось рыть дальше.

А дальше нашлись две ооооочень интересные публикации, которые непосредственно с MariaDB не связаны, но зато связаны с MySQL, а проблемы, как оказалось, у них общие.

Для интересующихся – 17 лет небезопасному MySQL клиенту и Доверие mysqldump и небезопасному MySQL клиенту приводит к удаленному исполнению кода. Заголовки конечно кликбейтные, но давайте посмотрим в чем дело?

Исполнение кода во время импорта или через mysql клиент

Постараюсь быть максимально краток – попробуйте исполнить этот код (он легко может быть частью вашего импортируемого файла SQL):

echo "system touch testfile.txt" | mysql; ls -l

Несмотря на то, что это как бы обычный SQL файл (мы сейчас напрямую передаем текст в mysql как это происходит при импорте), действия, которые он выполняет выходят далеко за пределы работы с базой данных. Он создает файл в вашей файловой системе. А может и другие действия выполнить. Далее все ограничивается фантазией автора. И права и ограничения на пользователей базы данных вам не помогут.

Проблема заключается в том, что mysql клиент через чур доверяет импортируемому файлу, чего делать не следует. Понятно, что вы тщательно разделяете права по пользователям базы данных, но не все знают, что скрипты могут выполнять действия за пределами прав MySQL.

Оказывается об этой проблеме говорили в сообществе MariaDB в 2020 году здесь и даже в сообществе MySQL в 2007 году тут. То есть о проблеме известно еще с 2007 года (отсюда и кликбейт про 17 лет).

Помимо команды system есть еще и pager – вот иллюстрация с ним:

$ rm -f a_file; mysql; ls -l a_file

> pager touch a_file; select 1; exit;
PAGER set to 'touch a_file'
1 row in set (0.00 sec)

Bye
-rw-r--r-- 1 jgagne jgagne 0 Apr 10 14:40 a_file

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

Причем это работает в обе стороны. Например, вы можете выполнить какую-то работу на чужом сервере и забрать оттуда бекап. Или просто кто-то с вами может поделиться бекапом сайта и попросить что либо сделать – типичный сценарий на kwork и любой фриланс бирже... Сколько векторов атаки на разработчиков открывается внезапно! Хотя ни одной злонамеренной команды php, которые мы привыкли тщательно проверять там не будет – никто же не подумает что, в файле импорта msqyl была такая команда, которая может вмешаться в работу вашей системы. И причем после самого импорта полученная база будет абсолютно чистой!

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

Особенно в рамках понимания того факта, что до сих пор абсолютное большинство виртуальных (shared) хостингов все еще используют MySQL 5.7, чья поддержка завершилась практически год назад (осенью 2023).

Что делать?

Самый кардинальный и правильный способ предложила MariaDB – они ввели специальный режим sandbox mode, который включается с помощью аргумента --sandbox в mariadb клиенте или с помощью той самой пресловутой строки \- которая ломает импорт на старых клиентах.

Причем если с первым аргументом все понятно и очевидно – хочешь дополнительной безопасности? Используй аргумент! Но вот с первой строкой которую генерирует команда mariadb-dump и которую на момент публикации статьи нельзя было отключить, мне решительно не понятно – можно же было поступить точно так же – добавить специальный аргумент, который либо включает либо отключает эту окаянную строку?

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

Для mysql клиента есть один не очень очевидный аргумент, который можно использовать при импорте файлов --binary-mode. Неизвестно по какой причине – то ли так задумано, то ли случайно, но он помогает избежать нежелательного поведения при импорте файлов.

Если нужно исправить поведение самого mysql клиента, то можно использовать замещающий скрипт, который запретит создание подпроцессов. Подробнее описано здесь.

Выводы

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

Внятной реакции от MySQL пока нет, хотя Jean-François Gagné уже сделал им баг-репорт и все еще ждет ответа.

Надеюсь, что все кто начнет сталкиваться с ошибкой импорта MySQL файлов созданных с помощью новых версий MariaDB попадут на эту статью на хабре и сумеют решить свои проблемы максимально быстро.

Если у вас есть свои соображения по этому поводу – добро пожаловать в комментарии. Если будет новая информация по этому поводу – буду обновлять статью. Постараюсь всех держать в курсе ситуации с этим поведением mysql и mariadb.