flawopen.com/SQL Injection in PHP/Doctrine ORM
O Doctrine ORM é seguro contra injeção SQL?
Sim para DQL com parâmetros vinculados. Montar DQL ou SQL nativo por concatenação reabre o mesmo risco de qualquer consulta bruta.
$em->createQuery( "SELECT u FROM User u " . "WHERE u.id = $userId" );
$qb->select('u')
->from('User', 'u')
->where('u.id = :id')
->setParameter('id', $userId);
Valores vinculados não protegem a estrutura da consulta
setParameter() vincula valores DQL, que o Doctrine converte em parâmetros SQL separados do texto da consulta. Concatenar entrada em createQuery() ignora essa proteção. O mesmo vale para SQL nativo: Connection::executeQuery() é seguro com placeholders e uma lista de parâmetros, mas não quando a entrada é interpolada na string SQL.
Parâmetros não substituem identificadores
Um placeholder representa um valor, não um identificador DQL, coluna SQL, nome de tabela, operador ou direção de ordenação. A documentação de segurança do ORM alerta que entrada do usuário em métodos de expressão do QueryBuilder ainda pode formar DQL injetável. Mantenha essas expressões no código confiável e mapeie campos e direções escolhidos pelo usuário por uma lista de permissões estrita.
$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);
- ✓Vincule todo valor externo com setParameter() ou placeholders DBAL; nunca o concatene em DQL ou SQL.
- ✓Trate métodos de expressão do QueryBuilder e fragmentos DQL como código. Use listas de permissões para campos, direções, operadores e funções escolhidos pelo usuário.
- ✓Para SQL nativo, use executeQuery($sql, $params) ou executeStatement($sql, $params) com placeholders.
- ✓Revise o fluxo dos dados e a estrutura da consulta. Um valor parametrizado ainda pode expor registros não autorizados; aplique autorização separadamente.
Como revisar sua base de código
rg -n -g '*.php' 'createQuery\(|orderBy\(|addOrderBy\(|executeQuery\(' .Fontes e referências
- Doctrine ORM — parâmetros no QueryBuilder
- Doutrina ORM — segurança
- Doctrine DBAL — consultas preparadas e parâmetros
- FlawOpen — injeção SQL em PHP