Я хочу использовать функцию Doctrine DBAL executeQuery следующим образом:
$conn = DBAL\DriverManager::getConnection($connectionParams, $config);
$sql = "SELECT count(*) FROM clients WHERE client_id = :id";
$results = $conn->executeQuery($sql, ['id' => 'foo'], ['id' => \PDO::PARAM_STR]);
var_dump($results->fetchAll());
var_dump($results->rowCount());
Который работает нормально, возвращаясь:
array (size=1)
0 =>
array (size=1)
'count(*)' => string '1' (length=1)
int 1
Однако код также работает с использованием следующих строк (где параметры типов объявлены неправильно или вообще не объявлены):
$results = $conn->executeQuery($sql, ['id' => 'foo'], ['id' => \PDO::PARAM_INT]);
$results = $conn->executeQuery($sql, ['id' => 'foo'], ['notatag' => \PDO::PARAM_STR]);
$results = $conn->executeQuery($sql, ['id' => 'foo']);
Предложение о том, что объявление типа связанной переменной не используется, вызывает опасения относительно того, защищено ли это от внедрения SQL.
Я что-то здесь не так делаю? Как я могу быть уверен, что мой код безопасен?
Перечитав документацию по DBAL, я наткнулся на этот камень:
Если вы не указали целое число (через константу PDO :: PARAM *) ни для одного из методов привязки параметров, кроме строки, Doctrine DBAL попросит слой абстракции типа преобразовать переданное значение из своего PHP в представление базы данных.
Таким образом, не определяя $types
Параметр вы оставляете на усмотрение Doctrine для явного преобразования типа.
Но насколько это безопасно? В Doctrine есть что сказать при описании «правильного» способа включить «пользовательский ввод в ваши запросы»:
Помимо параметров привязки вы также можете передать тип переменной. Это позволяет Doctrine или соответствующему поставщику не только избежать, но и привести значение к правильному типу.
Предлагая с точки зрения безопасности $types
параметр является необязательным.
Других решений пока нет …