php SQL PDO-> Fetch () проблема - PullRequest
       2

php SQL PDO-> Fetch () проблема

0 голосов
/ 31 августа 2011
<?php
$g_id=$_GET['gid'];

// $one = $pdo->query("SELECT * FROM contactgroups WHERE id=".$g_id);
// $result = $one->fetch();
?>

Rename groupname: <input type="text" placeholder="<?php // $one['gr_name']; ?>">

Вот мой маленький код, который просто не работает, и я не могу найти то, что сделал неправильно.Любая помощь будет оценена.

Ответы [ 2 ]

4 голосов
/ 31 августа 2011
  • Ваш PHP-код комментируется
  • Вы не звоните echo
  • Вы используете $one вместо $result
  • ВыВы не дезинфицируете ввод, который не вызывает эту проблему, но это то, что должно быть исправлено.Санитарная обработка так же проста, как $g_id = intval( $_GET['gid'] );, но я советую изучить подготовленные заявления .

Сказав это, это должно работать:

<?php
$g_id=$_GET['gid']; 

$one = $pdo->query("SELECT * FROM contactgroups WHERE id=".$g_id);
$result = $one->fetch();
?>

Rename groupname: <input type="text" placeholder="<?php echo $result['gr_name']; ?>">
2 голосов
/ 31 августа 2011

Результат сохраняется в массиве $result, а не в объекте PDO $one. Это также нуждается в эхо, если вы не собираетесь использовать короткие ярлыки.

<input type="text" placeholder="<?php echo $result['gr_name']; ?>">

Я бы использовал ярлыки, так что если в настройках PHP они включены, но они устарели в PHP 5.6:

<input type="text" placeholder="<?= $result['gr_name']; ?>">

Пока вы можете использовать ярлыки, и я буду продолжать их использовать, чтобы протестовать против удаления этой невероятно полезной функции. Устаревшие ярлыки сломают множество тем WP и простых шаблонных движков!

Вам также следует рассмотреть возможность использования подготовленных заявлений . Без них этот скрипт уязвим для SQL-инъекций.

<?php
$query = $pdo->prepare("SELECT * FROM contactgroups WHERE id=:id");
if( $query->execute(array(':id' => $_GET['id'])) ) {
    $result = $query->fetch();
?>
<input type="text" placeholder="<?php echo $result['gr_name']; ?>" />
<?php } ?>

Как PDO предотвращает SQL-инъекцию (слишком долго, чтобы добавить комментарий - прокрутите вниз, чтобы увидеть лучшее объяснение)
Начнем с запроса:

mysql_query("DELETE FROM users WHERE id='".$id."'");

Если $id = "' OR 1=1 --";, то запрос будет выглядеть следующим образом при отправке в MySQL (- означает начало комментария):

DELETE FROM users WHERE id='' OR 1=1 --'

Очевидно, что последующее уничтожение может быть катастрофическим и, возможно, необратимым (если у вас нет умных администраторов БД). Исправление здесь, вместо использования длинного mysql_real_escape_string() (я действительно никогда не понимал, почему имя функции было настолько многословным, во-первых), теперь мы можем использовать подготовленные операторы PDO.

По PDO::preparing() заявлению, что вы отправляете сообщение в вашу БД с указанием сохранить и оптимизировать этот запрос, потому что он будет использоваться позже. Ваша БД хранит оптимизированный запрос, внимательно следя за тем, где находятся данные.

$statement = $pdo->prepare('DELETE FROM users WHERE id=:id');

PDO предоставит вам экземпляр PDOStatement , для которого вы можете PDO::bindParam() значений и выполнить их. Итак, давайте сделаем это и выполним.

$statement->bindParam(':id', $id);
$statement->execute();

Теперь какая-то закулисная магия происходит здесь. PDO отправляет данные в MySQL. MySQL проверяет данные и вставляет их в подготовленный оператор. Зная, где данные должны были быть размещены и как долго были вставлены данные, MySQL может определить диапазоны символов в запросе, который не нужно выполнять (читай: данные). Поэтому, когда хакер пытается выполнить SQL-инъекцию, MySQL даже не беспокоится об оценке чего-либо, связанного с подготовленным оператором.

  1. PDO сообщает MySQL, "The data for :id is ' OR 1=1 --"
  2. MySQL находит место, где: id был в подготовленном операторе. (В данном примере символ 28)
  3. MySQL считает длину данных (в данном случае 11 символов)
  4. MySQL выполняет математику 1-го класса и помнит, что все символы от 28 до 39 должны рассматриваться как символы.
  5. MySQL вставляет данные, и теперь запрос выглядит так:

    DELETE FROM users WHERE id=' OR 1=1 --

  6. Однако, поскольку он знает положение данных, MySQL только анализирует все, что находится за пределами каналов (|), для команд и ключевых слов.

    DELETE FROM users WHERE id=|' OR 1=1 --|

Таким образом, текст между трубами фактически никогда не анализируется. Когда MySQL требуется сравнить идентификаторы, он все равно сравнивает идентификаторы в таблице с данными, но поскольку данные никогда не выполнялись, внедрение SQL завершается неудачей.

Лучшее объяснение того, как PDO предотвращает SQL-инъекции

Когда мы готовим оператор с помощью PDO, он уведомляет базу данных о предстоящем запросе и о том, где будут находиться данные в запросе. Когда мы связываем данные с этим запросом и выполняем его, база данных выполняет некоторые закулисные действия, чтобы убедиться, что SQL-инъекции сорваны.
Давайте возьмем это за кулисами работу в другом контексте. Вы управляете блогом PHP, чей движок вы написали полностью самостоятельно. Вы гордитесь умной системой комментариев, которую вы написали, пока какой-то придурок не решит опубликовать этот комментарий:

<script type="text/javascript">
alert('You just been H4X0RED!!!!1 LOLS');
</script>

После того, как вы выкриките четыре буквенные слова на экране компьютера и убедитесь, что сценарий, который родители малыша больше никогда не пускают в Интернет, вы устраняете уязвимость XSS в своем коде с помощью htmlspecialchars().

$comment_text = htmlspecialchars($_POST['comment_text']);

Теперь, что ты здесь сделал? Когда в 3 часа ночи просыпается сценарист и проскальзывает к своему компьютеру, чтобы снова попробовать код, htmlspecialchars() превращает его неудачную попытку юмора в бесполезный беспорядок. Функция принимает любой важный в HTML символ (а именно < и >) и превращает их в буквальное значение (&lt; и &gt;).

&lt;script type=&quot;text/javascript&quot;&gt;
alert('You just been H4X0RED!!!!1 LOLS');
&lt;/script&gt;

Анализатор HTML в браузере каждого пользователя интерпретирует &lt не как начало тега HTML, а как признак фактического вывода символа <. По сути, это то, что делает механизм базы данных со всеми данными, введенными в подготовленные операторы. За исключением случаев, когда буквы SQL составляют допустимые команды (а также действительные данные), механизм интерпретирует все символы в данных как их буквальное значение. Так что вместо:

DELETE FROM users WHERE id = 0 OR 1=1 --'

Он оценивает каждый символ в данных как его буквальное значение. В HTML это будет:

DELETE FROM users WHERE id = &#48;&#32;&#79;&#82;&#32;&#49;&#61;&#49;&#32;&#45;&#45;&#39;

Если вы посмотрите на оба здесь , они оба выводят одно и то же, за исключением второго, «данные» интерпретируются синтаксическим анализатором как его буквальное значение, а не как функциональное значение. SQL делает то же самое. Используя буквальное значение данных, ни один из фактических данных не может быть интерпретирован как команда или часть одного.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...