Вывод данных из MySQL

max74max

Новичок
Нет.
Это работает не для любых данных, а подготовленные выражения - для любых.
Можно, пожалуйста, пример для каких данных это может не работать?
А если использовать жесткую фильтрацию вводимых данных, например через регулярку?

Я конечно понял, что лучше подготовленные выражения, но вопрос заключается в том, чтобы исключить возможность SQL инъекции именно при таком коде, где не используются подготовленные выражения.
 

Фанат

oncle terrible
Команда форума
Ну началась тоговля.
Господи, говнякай как придется, никому все равно твой курсач не нужен. преподы знают еще меньше тебя.
С какого перепугу тебя вдруг безопасность запросов озаботила? Как будто остальные части кода сильно лучше.
 

WMix

герр M:)ller
Партнер клуба
А если использовать жесткую фильтрацию вводимых данных, например через регулярку?
тогда окажется что твоя программа не способна вписать в текстовое поле SQL как текст как мы это делаем тут на форуме

Можно, пожалуйста, пример для каких данных это может не работать?
PHP:
$id = mysql_real_escape_string("1 OR 1=1");   
$sql = "SELECT * FROM table WHERE id = $id";
первое что в голову приходит

проблема не в том что это можно отловить, (в данном случае простым (int)), а в том что об этом можно просто не думать, и тупо использовать подготовленные выражения. это сделает программу еще и читабильной,
множество IDE заточены под подготовленные выражения и предлагают выполнить запрос с любыми значениями. но тебя все это не убедит, ты настырный, представляешь из себя как супермена способного предотвратить все возможные вхождения, наивно полагая что все под контролем. ты даже не думаешь что эту программу придется поправлять через пару месяцев, когда уже полностью забыл, но приходится внедрять доп функционал. а тебе будет уже до фонаря все эти иньекции. а тут еще и помошник появится которому придется рассказывать как и где правильно кастить.

просто пойми что нет безопасного способа переходить 6-ти полосную дорогу в неположенном месте
 

max74max

Новичок
Ну началась тоговля.
Господи, говнякай как придется, никому все равно твой курсач не нужен. преподы знают еще меньше тебя.
С какого перепугу тебя вдруг безопасность запросов озаботила? Как будто остальные части кода сильно лучше.
Причем тут преподы и учеба?
Мне 32 года и я делаю свой сайт, поэтому меня и заинтересовала безопасность.
 
Последнее редактирование:

max74max

Новичок
проблема не в том что это можно отловить, (в данном случае простым (int)), а в том что об этом можно просто не думать, и тупо использовать подготовленные выражения. это сделает программу еще и читабильной,
множество IDE заточены под подготовленные выражения и предлагают выполнить запрос с любыми значениями. но тебя все это не убедит, ты настырный, представляешь из себя как супермена способного предотвратить все возможные вхождения, наивно полагая что все под контролем. ты даже не думаешь что эту программу придется поправлять через пару месяцев, когда уже полностью забыл, но приходится внедрять доп функционал. а тебе будет уже до фонаря все эти иньекции. а тут еще и помошник появится которому придется рассказывать как и где правильно кастить.

просто пойми что нет безопасного способа переходить 6-ти полосную дорогу в неположенном месте

Ок, я понял. Буду переписывать код и использовать подготовленные выражения. Благодарю за доходчивое разъяснение.
У меня получилось так:

PHP:
$id = $_GET['id'];
$id = $mysqli->real_escape_string($id);

$stmt = $mysqli->prepare("SELECT * FROM `users` WHERE id = ? LIMIT 1");

$stmt->bind_param("s", $id);
$stmt->execute();
$result = $stmt->get_result();

while ($row = mysqli_fetch_assoc($result)) {
$name = $row["name"];
}
   mysqli_free_result($result);

echo $name;
Но что-то не могу сообразить как тоже самое сделать здесь:

PHP:
$name = $_GET['name'];
$name = $mysqli->real_escape_string($name);
$city = $_GET['city'];
$city = $mysqli->real_escape_string($city);
$age = intval($_GET['age']);
$age = $mysqli->real_escape_string($age);


$result = $mysqli->query("INSERT INTO `table` (name,city,age) VALUES ('$name','$city','$age')");
   mysqli_free_result($result);
 

Фанат

oncle terrible
Команда форума
Господи, ну точно так же, только без дебильной escape string
  1. Заменить все переменные в запросе на специальные маркеры, которые называются плейсхолдеры или параметры, а по сути - просто знаки вопроса
  2. Подготовить запрос к исполнению с помощью функции prepare(). Эта функция принимает строку запроса и возвращает жкцемаляр специального класса mysqli_stmt, с которым в дальнейшем и производятся все манипуляции
  3. Привязать переменные к запросу с помощью bind_param(). Это очень интресная функция. Она принимает в качестве параметров все переменные, которые должны попасть в запрос, в том же самом порядке, в котором стоят прлейсхолдеры в запросе. Но кроме того, сначала в этой функции должны быть указаны типы для всех переменных, в виде строки, где тип переменной обозначается одной буквой. То есть букв в этой строке должно быть ровно столько, сколько дальше будет переменных. К счастью, можно особо не париться с типами и для всех переменных указывать тип "s".
  4. Выполнить запрос с помощью с помощью execute(). Эта функция выполняется без параметров
 

WMix

герр M:)ller
Партнер клуба
Но что-то не могу сообразить как тоже самое сделать здесь:
ну также,
Код:
$stmt = $mysqli->prepare("INSERT INTO `table` (name,city,age) VALUES (?,?,?)");
$stmt->bind_param("s",$name);
$stmt->bind_param("s",$city);
$stmt->bind_param("s",$age);
$stmt->execute();
только обрати внимание на букву "s" сдается мне что в этой сточке
$stmt->bind_param("s", $id);
ты хотел чтото другое.
и да $id = $mysqli->real_escape_string($id); это не нужная строка да и не string это и LIMIT 1 это параноя
 
Последнее редактирование:

max74max

Новичок
и да $id = $mysqli->real_escape_string($id); это не нужная строка да и не string это
Получается из-за того, что я буду использовать подготовленный запрос можно не переживать по поводу кавычек и не экранировать их, я верно понимаю?
Например если $name = "o'connor";
 

WMix

герр M:)ller
Партнер клуба
да, правильно думаешь, но проверь, не доверяй никому
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
все врут? 😁 вот же мозготрахальщики
А про проблемы передачи по ссылке в $stmt->bind_param не сказали.

@max74max еще один момент, параметр в метод bind_param передается по ссылке. Если ты используешь его в цикле, или между вызовом bind_param() и execute() есть другой код - значение может измениться, и в запрос пойдет совсем не то, что ты ожидал. Лучше пиши bindValue()
 

Фанат

oncle terrible
Команда форума
Если ты используешь его в цикле, или между вызовом bind_param() и execute() есть другой код - значение может измениться, и в запрос пойдет совсем не то, что ты ожидал. Лучше пиши bindValue()
Гриша, как протрезвеешь, поправь свой глубокомысленный текст, чтобы он нёс хоть какой-то смысл ;)
 

Фанат

oncle terrible
Команда форума
Получается из-за того, что я буду использовать подготовленный запрос можно не переживать по поводу кавычек и не экранировать их, я верно понимаю?
Например если $name = "o'connor";
правильно
только делай по моей инструкции, эти два нетрезвых гражданина тебя только запутают
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Гриша, как протрезвеешь, поправь свой глубокомысленный текст, чтобы он нёс хоть какой-то смысл ;)
😁 шикарный софизм

меняю пример из документации:
PHP:
<?php
$i=$_GET['i']?:0;
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE id = :id');
$sth->bindParam(':id', $i);

foreach ([1,2,3] as $i) {
  echo $i++;
}
$sth->execute();
Получаем фигню - значение параметра будет взято из $i в момент вызова execute(), а не то, что передали в bindParam().
На 10 строках это легко увидеть, а с ООП головного мозга можно влипнуть. С bindValue() проблем нет.
 

Фанат

oncle terrible
Команда форума

grigori

( ͡° ͜ʖ ͡°)
Команда форума
хм, bindParam в PDO и bind_param в mysqli одинаково принимают по ссылке,
а тупо перенос биндинга внутрь цикла не меняет ничего
 

Фанат

oncle terrible
Команда форума
хм, bindParam в PDO и bind_param в mysqli одинаково принимают по ссылке,
а тупо перенос биндинга внутрь цикла не меняет ничего
да, только в mysqli нет никакого bind_value в принципе
проблема с биндингом решается при помощи ООП головного мозга - подготовка запроса и выполнение выполняются не кишками наружу в коде, а инкапсулировано в функцию. То есть у тебя нет вариантов кроме

PHP:
$i=$_GET['i']?:0;
foreach ([1,2,3] as $i) {
    echo $i++;
}
$db->preparedQuery('SELECT name, colour, calories FROM fruit WHERE id = :id', ['id' => $id]);
Но вообще по сути замечание конечно верное.
Просто для mysqli довольно бесполезное :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
вообще, я просто забыл про существование mysqli, не встречал его уже лет ... 7?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
блин, какой жуткий легаси этот mysqli_stmt::bind_param()
написано, что параметры он принимает по ссылке, но в примере передача константы
PHP:
$stmt->bind_param('sssd', $code, $language, $official, $percent);
по стандартам 8ки любая передача значения в парметр, который принимает по ссылке, приводит к fatal error https://3v4l.org/8hVVK
зарепортить что-ли?

единственное, что можно сделать - никогда не использовать mysqli, он существует только ради совместимости с php 4
 
Сверху