flawopen.com/SQL Injection in PHP/Doctrine ORM
Защищает ли Doctrine ORM от SQL-инъекций?
Да, если значения в DQL передаются параметрами. Конкатенация DQL или SQL возвращает риск обычного сырого запроса.
$em->createQuery( "SELECT u FROM User u " . "WHERE u.id = $userId" );
$qb->select('u')
->from('User', 'u')
->where('u.id = :id')
->setParameter('id', $userId);
Связанные значения не защищают структуру запроса
setParameter() связывает значение DQL, которое Doctrine преобразует в отдельный SQL-параметр. Конкатенация в createQuery() обходит эту защиту. То же для SQL: Connection::executeQuery() безопасен с плейсхолдерами и массивом параметров, но не при вставке ввода в строку SQL.
Параметром нельзя заменить идентификатор
Плейсхолдер задаёт значение, а не идентификатор DQL, столбец SQL, таблицу, оператор или направление сортировки. Руководство ORM предупреждает: пользовательский ввод в методах выражений QueryBuilder всё ещё может сформировать DQL-инъекцию. Оставляйте выражения в доверенном коде и выбирайте поля и порядок только из строгого списка разрешённых значений.
$qb->orderBy(
'u.' . $request->query->get('sort'),
$request->query->get('direction')
);
$fields = [
'name' => 'u.name',
'created' => 'u.createdAt',
];
$directions = ['asc' => 'ASC', 'desc' => 'DESC'];
$key = (string) $request->query->get('sort', 'name');
$sort = $fields[$key] ?? $fields['name'];
$requestedDirection = strtolower(
(string) $request->query->get('direction', 'asc')
);
$direction = $directions[$requestedDirection] ?? 'ASC';
$qb->orderBy($sort, $direction);
- ✓Связывайте внешние значения через setParameter() или плейсхолдеры DBAL; не конкатенируйте их с DQL или SQL.
- ✓Считайте методы выражений QueryBuilder и фрагменты DQL кодом. Разрешайте только утверждённые поля, сортировку, операторы и функции.
- ✓Для SQL используйте executeQuery($sql, $params) или executeStatement($sql, $params) с плейсхолдерами.
- ✓Проверяйте поток данных и структуру запроса. Параметризованное значение всё равно может открыть неразрешённые записи; отдельно проверяйте права доступа.
Проверка кодовой базы
rg -n -g '*.php' 'createQuery\(|orderBy\(|addOrderBy\(|executeQuery\(' .Источники и ссылки
- Doctrine ORM — параметры QueryBuilder
- Doctrine ORM — безопасность
- Doctrine DBAL — подготовленные запросы и параметры
- FlawOpen — SQL-инъекция в PHP