Поэтому в основном я копал глубоко в области MySQL и PHP … в частности, меры безопасности, которые я должен принимать при работе с базой данных и вводами форм. До сих пор я нашел, что настоятельно рекомендуется следующее:
Все это здорово, и я слежу за ним. Тем не менее, мне было интересно, следует ли избегать символов, таких как знак доллара [$], знак процента [%] и, возможно, другие. Не мог ли запрос интерпретировать знак доллара как переменную PHP, возможно? Что о синтаксисе LIKE, который я слышал, использует символ% или даже знак подстановки? Подготовленные заявления должны технически позаботиться обо всем этом, но я просто хотел быть в безопасности и убедиться, что у меня все ускользнуло должным образом. В случае, когда я забываю использовать подготовленные заявления или просто пренебрегать ими, я надеялся, что эта вторая линия обороны может сказать мне, что я могу избавиться от головокружения.
Вот что я сейчас использую для экранирования:
function escape($connection, $data){ $new_data = trim($data); $new_data = mysqli_real_escape_string($connection, $new_data); $new_data = addcslashes($new_data, '%_$'); $new_data = htmlspecialchars($new_data, ENT_NOQUOTES); return $new_data; }
Так это правильно? Я делаю что-то ужасно неправильно? Обратите внимание, что при возврате данных базы данных мне придется удалить обратные косы перед символами $,% и _.
Я делаю что-то ужасно неправильно?
Да.
Подготовленные заявления – единственная замечательная вещь, которую вы нашли.
Хотя использование mysqli_real_escape_string (при условии, что вы используете подготовленные инструкции) было бы бесполезным и вредным (создавая результат, который вы отметили сами: «Вы назвали isn \ t …»).
И Magic Quotes уже давно удалены с языка – таким образом, на самом деле ничего не стоит.
Таким образом, даже большинство ваших первоначальных помещений явно ошибочны.
Не мог ли запрос интерпретировать знак доллара как переменную PHP, возможно?
Нет.
Что о синтаксисе LIKE, который я слышал, использует символ% или даже знак подстановки?
Да, вы слышали это правильно. Точная цель оператора LIKE – выполнить поиск по шаблону. Отключение этих символов в LIKE не имело бы ни малейшего смысла.
Каждый раз, когда вы собираетесь использовать LIKE-оператор, вы должны решить, какой конкретный символ использовать и который запретить. Нельзя использовать одноразовое решение. Не говоря уже о том, что во всех других взаимодействиях mysql знак% не имеет никакого особого значения.
Подготовленные заявления должны технически позаботиться обо всем этом
Подготовленные утверждения не имеют ничего общего ни с $, ни с знаками%. Подготовленные утверждения относятся к SQL-инъекциям, но ни один символ не может вызвать его (не могли бы вы назвать «инъекцию» надлежащим образом используемым оператором LIKE, не так ли?).
В случае, если вы забудете использовать подготовленные заявления или просто пренебрегаете их выполнением,
И наименьшая помощь была бы от той функции, которую вы разработали.
%
и _
символы во входных данных, только если они будут использоваться в LIKE-операторе, и вы не хотите, чтобы их интерпретировали. * прочитайте подготовленные заявления, если этот термин вам незнаком.
Вам не нужно избегать знака доллара. MySQL не рассматривает этот характер специально, и PHP только распознает его в исходном коде, а не в строковых значениях (если вы не вызываете eval
в строке, но это целая другая червь из червей).
Вам нужно будет только избежать %
и _
если вы использовали пользовательский ввод в качестве аргумента LIKE
и вы не хотели, чтобы пользователь мог использовать подстановочные знаки. Это может возникнуть, если вы обрабатываете форму поиска. Вам не нужно использовать его при хранении в базе данных.
При доступе к базе данных вам не нужно использовать htmlspecialchars
. Это следует использовать только при отображении данных пользователю на странице HTML, чтобы предотвратить внедрение XSS.
В зависимости от того, какие данные и для чего они используются.
Если вы обнаружите, что готовые заявления по умолчанию PHP слишком велики и сложны, я предлагаю взглянуть на некоторые классы, доступные на github, чтобы дать вам представление об упрощенных запросах.
Хороший пример @ https://github.com/joshcam/PHP-MySQL-Database-Class
Пример вставки запросов с этим классом
$data = Array ( 'login' => 'admin', 'active' => true, 'firstName' => 'John', 'lastName' => 'Doe', 'password' => $db->func('SHA1(?)',Array ("secretpassword+salt")), // password = SHA1('secretpassword+salt') 'createdAt' => $db->now(), // createdAt = NOW() 'expires' => $db->now('+1Y') // expires = NOW() + interval 1 year // Supported intervals [s]econd, [m]inute, [h]hour, [d]day, [M]onth, [Y]ear ); $id = $db->insert ('users', $data); if ($id) echo 'user was created. Id=' . $id; else echo 'insert failed: ' . $db->getLastError();