[SendIt 2.5.0] Дополнительная защита от SQL-инъекций
Приветствую! Если коротко, то с версии 2.5.0 компонент принудительно прогоняет все поступающие с фронта данные через паттерн для очистки о возможных SQL-инъекций. Чуть подробнее под катом
В целом, я надеюсь что вы используете для формирования запросов к базе данных методы класса xPDOQuery. Предполагается, что там уже есть защита от SQL-инъекций, но безопасности не бывает много. В связи с этим я добавил класс Sanitazer с одним единственным методом process для обработки данных.
Паттерн по которому происходит фильтрация выглядит так
Входе испытаний было выявлено, что данный паттерн портит адреса электронной почты, поэтому значения похожие на них были исключены из проверки следующим образом
Спасибо за внимание!
В целом, я надеюсь что вы используете для формирования запросов к базе данных методы класса xPDOQuery. Предполагается, что там уже есть защита от SQL-инъекций, но безопасности не бывает много. В связи с этим я добавил класс Sanitazer с одним единственным методом process для обработки данных.
Паттерн по которому происходит фильтрация выглядит так
private const DANGEROUS_PATTERNS = [
'/\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|EXEC|EXECUTE|TRUNCATE|ALTER|CREATE|SHOW|DESCRIBE|GRANT|REVOKE|COMMIT|ROLLBACK|MERGE|CALL)\b/i',
'/;.*--/',
'/\/\*.*\*\//',
'/--\s+/',
'/#.*$/',
'/WAITFOR\s+DELAY/i',
'/XP_/i',
'/sp_/i',
'/@@/',
'/@\w+/',
'/CHAR\(\d+\)/',
'/0x[0-9A-Fa-f]+/',
'/BENCHMARK\(/i',
'/SLEEP\(/i',
'/LOAD_FILE\(/i',
'/INTO\s+(OUTFILE|DUMPFILE)/i',
'/CONCAT_WS\(/i',
'/GROUP_CONCAT\(/i',
'/INFORMATION_SCHEMA/i',
'/sys\./i',
'/pg_/i'
];
Придумал его Deepseek, так что все претензии к нему)))Входе испытаний было выявлено, что данный паттерн портит адреса электронной почты, поэтому значения похожие на них были исключены из проверки следующим образом
if(preg_match(self::EMAIL_REGEXP, $input)){
return $input;
}
И конечно же, чтобы вы, дорогие коллеги, могли творить любую дичь, было добавлено событие senditOnSetValue, в котором можно оставить исходное значение или сделать дополнительные проверки, или исключить отдельные поля из проверки.Спасибо за внимание!
Поблагодарить автора
Отправить деньги
Комментарии: 5
Безопасность MODX для меня не слишком понятная тема. Когда то искал как безопасно писать запросы в базу. Нашел только приводить к инт все id получаемые с фронта. И плюс вырезать из получаемого с фронта теги MODX и fenom. Было бы интересно увидеть разбор безопасности MODX, при запросах в базу. И увидеть примеры атак, чтобы знать от чего защищаться.
Я тоже далеко не специалист в безопасности, но точно знаю, что надо валидировать пользовательский ввод, поэтому и добавил этот функционал в SendIt.
К сожалению, не понимая думаю можно наделать других дырок. Попробовал проверить на уязвимость из https://habr.com/ru/articles/130826/ .

Вроде не уязвимо :-). Почти все через pdoFetch идет. Только иногда использую сложное условие вроде (id IN (2,3) and (parent = 4 or parent IS NULL)) в where. Тогда… хм. проверю :-).
Код для проверки:

Вроде не уязвимо :-). Почти все через pdoFetch идет. Только иногда использую сложное условие вроде (id IN (2,3) and (parent = 4 or parent IS NULL)) в where. Тогда… хм. проверю :-).
Код для проверки:
<?php
$pdo = $modx->getService('pdoFetch');
$id = $_GET['id'];
$pdo->setConfig([
'class'=>'modResource',
'where'=>[
0=>"(id = $id and (parent = 4 or parent = 0))"
],
'limit'=>0,
'return'=>'data'
]);
$ress = $pdo->run();
foreach($ress as $res){
echo "<p>{$res['id']}</p>";
}
echo '<pre>'.$pdo->getTime().'</pre>';
На запрос gettables.ru/test.html?id=4+OR+1 выдало:1
2
3
4
5
6
7
14
16
19
20
21
22
25
30
0.0000529: xPDO query object created
0.0000019: Processed additional conditions
0.0000720: Added where condition: 0=(id = 4 OR 1 and (parent = 4 or parent = 0))
0.0000749: Sorted by modResource.id, ASC
0.0002530: SQL prepared "SELECT * FROM `modx_site_content` AS `modResource` WHERE (id = 4 OR 1 and (parent = 4 or parent = 0)) ORDER BY modResource.id ASC "
0.0014510: SQL executed
0.0000789: Rows fetched
0.0000720: Returning raw data
0.0167792: Total time
4 194 304: Memory usage
Выдало все id страниц. То есть 'where'=>[
0=>"(id = $id and (parent = 4 or parent = 0))"
],
Уязвимо для инъекций. Будем знать.
Вставлять сырые данные с фронта в запрос небезопасно, именно на этот случай мной и была добавлена принудительная проверка. Сам в начале этим грешил. А еще в pdo есть методы для подготовки запроса, это делает их чуть более безопасными. Тут можно почитать
Что РКН с инетом делает?? гитхаб не открывается, а впн помогло :-(
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.