PHP: заполнитель не работает для идентификатора в pdo [дубликат]

Конструкция цикла Java «для каждого» допускает итерацию над двумя типами объектов:

  • T[] (массивы любого типа)
  • java.lang.Iterable<T>

Интерфейс Iterable<T> имеет только один метод: Iterator<T> iterator(). Это работает над объектами типа Collection<T>, потому что интерфейс Collection<T> расширяет Iterable<T>.

11
задан Andrew 14 May 2014 в 18:21
поделиться

1 ответ

Можно ли использовать подготовленный оператор PDO для привязки идентификатора (имя таблицы или поля) или ключевое слово синтаксиса?

К сожалению, подготовленный оператор может представлять только литерал данных. Итак, очень распространенная ошибка - это такой запрос:

$opt = "id";
$sql = "SELECT :option FROM t WHERE id=?";
$stm  = $pdo->prepare($sql);
$stm->execute(array($opt));
$data = $stm->fetchAll();

Зависит от настроек PDO, этот запрос будет вызван либо ошибкой (в случае использования реальных подготовленных операторов), либо просто литеральной строкой 'id' в наборе полей (в случае эмулированных подготавливаний).

Итак, разработчик должен сам позаботиться об идентификаторах - PDO не предлагает никакой помощи в этом вопросе.

Чтобы сделать динамический идентификатор безопасен, нужно следовать двум строгим правилам:

  • правильно отформатировать идентификатор
  • , чтобы проверить его на жестком запросе белого списка.

Чтобы отформатировать идентификатор, нужно применить эти 2 правила:

  • Ввести идентификатор в обратные метки.
  • Сбросить обратные выходы внутри, удвоив их.

После такого форматирования безопасно вставить переменную $ table в запрос. Таким образом, код будет выглядеть следующим образом:

$field = "`".str_replace("`","``",$field)."`";
$sql   = "SELECT * FROM t ORDER BY $field";

Однако, хотя такого форматирования было бы достаточно для таких случаев, как ORDER BY, для большинства других случаев существует возможность для различного рода инъекций: разрешение пользователь может выбрать таблицу или поле, которое они могут видеть, мы можем выявить некоторую конфиденциальную информацию, такую ​​как пароль или другие личные данные. Таким образом, всегда лучше проверять динамические идентификаторы на список допустимых значений. Вот краткий пример:

$allowed = array("name","price","qty");
$key     = array_search($_GET['field'], $allowed);
$field   = $allowed[$key];
$query   = "SELECT $field FROM t"; //value is safe

. Правила ключевых слов одинаковы, но, конечно, нет форматирования - таким образом, возможен только белый список и должен использоваться:

$dir = $_GET['dir'] == 'DESC' ? 'DESC' : 'ASC'; 
$sql = "SELECT * FROM t ORDER BY field $dir"; //value is safe

См. также примечание, внесенное пользователем в документации PHP: Пользовательская заметка о PDO :: quote

23
ответ дан 4 revs, 2 users 94% 26 August 2018 в 18:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: