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;
}
Эта реализация имеет два серьезных изъяна:
- Ложные срабатывания (False Negative): Если в абсолютно валидном
SELECT-запросе внутри строкового литерала встречается точка с запятой (например, SELECT * FROM logs WHERE message = 'error; system halted'), split(';') вернёт 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)
Шаги воспроизведения
- Открыть любую таблицу MySQL в браузере
TableView и перейти в режим Custom SQL.
- Ввести запрос с точкой с запятой внутри строки:
SELECT * FROM users WHERE status = 'active; verified';
- Нажать Execute.
- Фактический результат: Запрос блокируется функцией
isAllowedMysqlSelectQuery из-за split(';').length > 1.
- Ожидаемый результат: Функция должна корректно игнорировать точки с запятой внутри строковых литералов (
'...' / "...") и комментариев (-- / /* ... */), а также лучше контролировать отсутствие модифицирующих конструкций (INTO OUTFILE, FOR UPDATE).
Acceptance Criteria / Критерии приемки
Summary / Описание проблемы
Проверка безопасности кастомных SELECT-запросов в браузере таблиц MySQL (
isAllowedMysqlSelectQueryвmysql_table_utils.dart) реализована крайне наивно:Эта реализация имеет два серьезных изъяна:
SELECT-запросе внутри строкового литерала встречается точка с запятой (например,SELECT * FROM logs WHERE message = 'error; system halted'),split(';')вернёт 2 элемента, и запрос будет ошибочно заблокирован с ошибкой безопасности.startsWith('select')позволяет выполнить запросы с побочными эффектами (например, вызов функций/процедур, модифицирующих данные внутри SELECT:SELECT my_dangerous_function();или экспорт файлов на сервереSELECT * FROM users INTO OUTFILE '/tmp/users.txt').Scope & Component
desktopMySQL Driver / Table Viewbugmediumdev / 0.5.0Местоположение в коде
lib/features/mysql/mysql_table_utils.dart(строки ~2-12, функцияisAllowedMysqlSelectQuery)Шаги воспроизведения
TableViewи перейти в режимCustom SQL.SELECT * FROM users WHERE status = 'active; verified';isAllowedMysqlSelectQueryиз-заsplit(';').length > 1.'...'/"...") и комментариев (--//* ... */), а также лучше контролировать отсутствие модифицирующих конструкций (INTO OUTFILE,FOR UPDATE).Acceptance Criteria / Критерии приемки
isAllowedMysqlSelectQueryвmysql_table_utils.dartпереписана с учетом токенизации или корректного игнорирования точек с запятой внутри строковых литералов и комментариев.SELECT * FROM table WHERE col = 'a;b'успешно проходят валидацию и выполняются.isAllowedMysqlSelectQueryна различные граничные случаи (строки с;, CTEWITH ... SELECT, комментарии).