Тут у меня появился вопрос. А чё всё что пападает в prepare например как у меня ниже PHP: $result= $db->prepare($this->Update . $this->tableName . ' SET ' . $stringUp . $this->where); $result->execute(); автоматически экранируется при добавлении в базу ?
В твоём виде - нет. А вообще - да. Идея в том, что обычный запрос идет в текстовом режиме, а значит надо экранировать сущности, которые влияют на строку. Кавычки, бэкслэши и тп. В подготовленном запросе на сервер сначала отправляется шаблон с позициями переменных, а потом отдельно уже докидываются значения этих переменных. В этом случае передаваемые строки уже не ломают запрос и можно обойтись без экранирования. Как минус - подготовленный запрос выполняется в 1 + N команд, то есть сначала отправляется сам шаблон, а потом N-раз данные для него. Если надо выполнить только один запрос, то этом может создать лишнюю нагрузку по сравнению с текстовым режимом обычных запросов. Но в случае с несколькими запросами с разными данными - дает преимущество, так как не нужно тратить время на очередной разбор текстового запроса.
Можешь привести пример в котором данные экранируются? Просто я не могу понять как мне правильно построить универсальный запрос который я бы вызывал методом например вот как у меня сейчас. PHP: //Функция добавления данных в таблицу БД public function Insert($arr) { $db = Db::getConnection(); $stringIns = ''; foreach ($arr as $key => $value) { $stringIns = $stringIns.', '.$key.'="'.$value.'"'; }; $stringIns = trim($stringIns, ', '); $result = $db->prepare($this->Insert . $this->tableName . ' SET ' . $stringIns); $result->execute(); }
Показываю на примере всеми любимой Жанны д'Арк Итак. Бабу зовут Jeanne d'Arc. Есть запрос вида PHP: SELECT '%name%' `name` где %name% должно принять нашу Жанну. Простой текстовый режим. Не экранируем и сразу подставляем значение переменной в строку: PHP: SELECT 'Jeanne d'Arc' `name` то есть ломается запрос А вот экранированное значение, подставленное в ту же строку: PHP: SELECT 'Jeanne d\'Arc' `name` всем хорошо. В процессе разбора сервер выделит из этой строки шаблон запроса и его данные. Условно шаблон будет как показано ранее с процентом, а данные - то как зовут бабу. То есть без экранов всяких. Подготовленный запрос будет отправлен в два этапа. Сначала шаблон условно с процентом, а потом отдельно уже название бабы. Поскольку они отдельно пришли, то строку запроса сломать невозможно - кавычки в имени не повлияют на кавычки в шаблоне запроса. Ура. ты сейчас формируешь текстовый запрос и передаешь его как шаблон подготовленного шаблона. А хочешь делать подготовленный запрос и потом подставлять в него данные.
Ещё в документации по pdo:repare есть хороший первый пример, с именованными ключами массива https://secure.php.net/manual/ru/pdo.prepare.php
@askanim В твоём случае я бы не делал подготовленные запросы, а проэканировал бы всё вручную. PHP: public function Insert($arr) { $db = Db::getConnection(); $stringIns = ''; // Не понятно, что там у тебя в $db, но предположим, что PDO $stringIns = []; // Можно и так, как у тебя, но мне больше нравится так foreach ($arr as $key => $value) { // PDO::quote сама добавляет апострофы $stringIns[] = sprintf("%s=%s", $key, $db->quote($value)); }; $stringIns = implode(",", $stringIns); $db->query($this->Insert . $this->tableName . ' SET ' . $stringIns); } А с подготовленными - это тебе надо было в запрос вместо данных расставлять вопросы: PHP: $stringIns=$stringIns.', '.$key.'=?'; А потом в execute() передать значения
Да я вкурсе в ручную так всегда и делал. Но в моём случае я по циклу забиваю сам запрос автоматически исходя и Да именно pdo там и есть
у тебя есть названия полей, ты должен им присвоить значения, эти названия полей прописаны в скрипте, их изменить нельзя пользователю, он их только может заполнять, вот из этих названий полей и делаешь sql шаблон для prepare, потом передаёшь массив где ключи названия этих полей, а значения которые передал пользователь
это библиотека, я использую DAO Оболочку запросов. Написал вон сам как выше показал, это не для, конечного пользователя а для разработчика. Если бы было для конечного пользователя ясен бы был пень что я сделал не что такое PHP: $result = $db->prepare(INSERT INTO 'Tablename' SET Value=:Value); $result->bindParam(':Value', $_POST['Value']); $result->execute(); // И если там не одно значение можно просто в execute передать массив. // Вот и всё... А я составляю оболочку запроса чтобы можно было сделать так ну у меня так собственно уже и можно $this->table('tablename')->Insert(['Где ключ массива имя столбца в таблице' => 'А значение ключа, подставляем переменную которую туда будем записывать полученной из пост']); //Как то так. Так вот я ума не приложил как prepare перебрать этот массив так чтобы составить такие вот
Затестил pdo->quote($value); Всё клёво но есть одно но символы типа Знаков '>' руинят сам php код и тд Затестил вот такой текст. PHP: %^^&!@$!R%$@#^*U&^(*&)!)@%$*#^%)#_@(_!&($&#$#^)$#)_%&?>BGF:N"GFN<:L<G<RGS>?<ZX<C?"PWFK
У меян проблема с экранированием спец символов... Я тут сунул с мана вот такую вот функцию, но она удаляет мне просто все теги.... PHP: function strip_tags_content($text, $tags = '', $invert = FALSE) { preg_match_all('/<(.+?)[\s]*\/?[\s]*>/si', trim($tags), $tags); $tags = array_unique($tags[1]); if(is_array($tags) AND count($tags) > 0) { if($invert == FALSE) { return preg_replace('@<(?!(?:'. implode('|', $tags) .')\b)(\w+)\b.*?>.*?</\1>@si', '', $text); } else { return preg_replace('@<('. implode('|', $tags) .')\b.*?>.*?</\1>@si', '', $text); } } elseif($invert == FALSE) { return preg_replace('@<(\w+)\b.*?>.*?</\1>@si', '', $text); } return $text; Мне нужно чтобы как ввели так и получили только чтобы это всё заэкранировалось и не ломало код.... Не могу понять какую функцию из обработки строк заюзать чтобы сделало что мне нужно... --- Добавлено --- решил проблему с тегами.... PHP: $postName = html_entity_decode($_GET['rout']); echo htmlentities($postName); // но один хрен вот такая строка ломает мне все просто //<div>Привет?">:""":":?>?#"%"@#:RT">>?">>:?>"?>"???"%#:%">%#"%,№"Э%№Ж%,Э%</div> ....
Что за чушь? Коду php по барабану, какие символы внутри строковых переменных (разве что с нулевым символом бывают проблемы, из-за того, что библиотеки написаны на C, а там нулевым символом конец строки отмечается. Но мне не разу не попадалась пока необходимость работы с нулевым символом на php)! Если ты про XSS, то там атака идёт не на код php, а на код HTML (чувствую разницу!), типа я ввёл тебе плохой нехороший javascript, и если ты неправильно выводишь данные, то этот код сработал. Поэтому: При добавлении в базу данных надо проэкранировать символы, которые могут порушить запрос с помощью PDO::quote, или с использованием подготовленых запросов При выводе данных, которые гарантированно не будут содержать текст html, прогнать их через htmlspecialchars Если нужно вывести данные, которые должны содержать html, но хочется себя обезопасить, нужно использовать либо стандартную функцию strip_tags, для того чтобы убрать все теги, кроме разрешённых, либо более мощные сторонние средства, к примеру HtmlPurifier (http://htmlpurifier.org/) Т.е. в базу мы записываем данные как есть, не портим их. А вот при выводе обрабатываем, чтоб не были возможны XSS-атаки
PHP: //<div>Привет?">:""":":?>?#"%"@#:RT">>?">>:?>"?>"???"%#:%">%#"%,№"Э%№Ж%,Э%</div> // У меня это строка не экронируется обрывается на пол пути // вот здесь //<div>Привет?">:""":":?>? - и дальше пусто даже скрипт не идёт дальше вообще весь.
Ничего ломать не должно после htmlentities. Этот бред должен быть показан как есть. http://phpfiddle.org/lite/code/7m6e-q5bm --- Добавлено --- Вот это нафига?
PHP: echo htmlentities($_GET['rout']); Не фига Вот строка в браузере... PHP: //http://sosed.ru/?rout=%3Cdiv%3E%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82?%22%3E:%22%22%22:%22:?%3E?#"%"@#:RT">>?">>:?>"?>"???"%#:%">%#"%,№"Э%№Ж%,Э%</div>
Ха Ты разгреби бардак в голове. Есть url-кодирование, есть сущности html, это разные вещи. https://secure.php.net/urlencode, https://secure.php.net/urldecode. urldecode для GET и POST параметров РНР делает сам
А получаю я в итоге вот что PHP: //<div>Привет?">:""":":?>? и мой скрипт нахрен дальше не идёт А если их кто нибудь возьмёт и отправит специально и они поломают мне код... Гет я просто проверяю так. Версия php 5.6 у меня.... --- Добавлено --- как не сломалось, наоборот и всё равно продолжает ломаться, просто не идёт дальше скрипт, обрывается на символах...
Ну ты эту строку в браузере сам так ввёл? Браузер нормально закодирует, и явно по-другому, поскольку символы вопроса точно должны быть url-кодированы
А не вот короче, понял скрипт дальше идёт, но он просто тек строку не читает если есть спец символы....
Привет?">:""":":?>? да вот всё что он передал --- Добавлено --- Спасибо, а что за xss атаки ? --- Добавлено --- это всё сделал вотс PHP: //Функция экранирующая данные при добавлении public function prepareDataBase ($arr) { $db = Db::getConnection(); $stringIns = []; foreach ($arr as $key => $value) { $stringIns[] = sprintf('%s=%s', $key, $db->quote($value)); }; return $stringIns = implode(', ', $stringIns); } //Функция добавления данных в таблицу БД public function Insert($arr) { $db = Db::getConnection(); $stringIns = $this->prepareDataBase($arr); $result = $db->query($this->Insert . $this->tableName . ' SET ' . $stringIns); } //Функция обновления данных в таблице БД public function Update($arr, $where = NULL) { $db = Db::getConnection(); $stringUp = $this->prepareDataBase($arr); if ($where != Null) { $this->where = $this->whereIs($where); } $result = $db->query($this->Update . $this->tableName . ' SET ' . $stringUp . $this->where); } --- Добавлено --- Я хочу чтобы если что - то через редактор например добавляется. Чтобы проходило через скрипт на сквозь как вписали. Но при этом серверный скрипт ни как не затронуло и базу не потревожило.