Skip to content

bug(mysql): custom SQL validation isAllowedMysqlSelectQuery suffers from false positives and negatives #274

Description

@ZhuchkaTriplesix

Summary / Описание проблемы

Проверка безопасности кастомных SELECT-запросов в браузере таблиц MySQL (isAllowedMysqlSelectQuery в mysql_table_utils.dart) реализована крайне наивно:

bool isAllowedMysqlSelectQuery(String sql) {
  final t = sql.trim();
  if (t.isEmpty) return false;
  final lower = t.toLowerCase();
  if (!lower.startsWith('select') && !lower.startsWith('with')) return false;
  final parts = t.split(';').where((s) => s.trim().isNotEmpty).toList();
  return parts.length <= 1;
}

Эта реализация имеет два серьезных изъяна:

  1. Ложные срабатывания (False Negative): Если в абсолютно валидном SELECT-запросе внутри строкового литерала встречается точка с запятой (например, SELECT * FROM logs WHERE message = 'error; system halted'), split(';') вернёт 2 элемента, и запрос будет ошибочно заблокирован с ошибкой безопасности.
  2. Пропуск потенциально опасных запросов (False Positive): Проверка только startsWith('select') позволяет выполнить запросы с побочными эффектами (например, вызов функций/процедур, модифицирующих данные внутри SELECT: SELECT my_dangerous_function(); или экспорт файлов на сервере SELECT * FROM users INTO OUTFILE '/tmp/users.txt').

Scope & Component

  • Scope: desktop
  • Component: MySQL Driver / Table View
  • Kind: bug
  • Severity: medium
  • Detected in version: dev / 0.5.0

Местоположение в коде

  • Файл: lib/features/mysql/mysql_table_utils.dart (строки ~2-12, функция isAllowedMysqlSelectQuery)

Шаги воспроизведения

  1. Открыть любую таблицу MySQL в браузере TableView и перейти в режим Custom SQL.
  2. Ввести запрос с точкой с запятой внутри строки: SELECT * FROM users WHERE status = 'active; verified';
  3. Нажать Execute.
  4. Фактический результат: Запрос блокируется функцией isAllowedMysqlSelectQuery из-за split(';').length > 1.
  5. Ожидаемый результат: Функция должна корректно игнорировать точки с запятой внутри строковых литералов ('...' / "...") и комментариев (-- / /* ... */), а также лучше контролировать отсутствие модифицирующих конструкций (INTO OUTFILE, FOR UPDATE).

Acceptance Criteria / Критерии приемки

  • Функция isAllowedMysqlSelectQuery в mysql_table_utils.dart переписана с учетом токенизации или корректного игнорирования точек с запятой внутри строковых литералов и комментариев.
  • Запросы типа SELECT * FROM table WHERE col = 'a;b' успешно проходят валидацию и выполняются.
  • Добавлены unit-тесты для isAllowedMysqlSelectQuery на различные граничные случаи (строки с ;, CTE WITH ... SELECT, комментарии).

Metadata

Metadata

Labels

bugSomething isn't workingcoreCore library logic and servicesmysqlMySQL database driver and workspace

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions