Я знаю, что должен использовать подготовленный оператор, но мой следующий проект будет использовать подготовленный оператор, я просто должен закончить это простое небольшое приложение.
Поэтому мой вопрос:
Является ли этот следующий фрагмент кода безопасным?
Я использовал htmlentities, а также mysql_real_escape_string, потому что думал, что это безопасный вариант.
//Image $imageInput = $_POST['Image']; $imageClean = htmlentities($imageInput, ENT_QUOTES, 'UTF-8'); //Inserts values into relevant field and creates a new row. mysql_query("UPDATE ***** SET image='" . mysql_real_escape_string($imageClean) . "' WHERE id=" . mysql_real_escape_string($idClean) . "");
для добавления кода для $ idClean:
//Id to change if(ctype_digit($_POST['testimonial'])) { $idInput = $_POST['testmonial']; $idClean = htmlentities($idInput, ENT_QUTOES, 'UTF-8'); }
Спасибо за вашу помощь.
ps, если вы могли бы предложить что-то добавить, это было бы здорово.
Зависит от того, насколько чист ваш $idClean
.
WHERE id=" . mysql_real_escape_string($idClean) . "
mysql_real_escape_string
только mysql_real_escape_string
обратную косую черту к \x00
, \n
, \r
, \
, '
, "
и \x1a
, но это не остановит злоумышленника, используя
$idClean = "1 OR 1=1 AND POSSIBLY OTHER SQL STATEMENTS"
Вместо mysql_real_escape_string
вам нужно просто преобразовать его в int.
Вы должны применять только экранирование объекта в точке вывода – нет никакого значения в том, чтобы избегать данных до вставки базы данных. Тем не менее, вы делаете правильные вещи с точки зрения mysql_real_escape_string.
Кроме того, поскольку @Piskvor говорит, что существует потенциальная проблема с переменной idClean. (Является ли это приведение к int, например?)
Вы можете использовать следующие, например:
mysql_real_escape_string(intval($idClean))
$ idClean откуда?
еще $ _POST? он должен быть целым числом, не так ли?
dont do html sanitization на нем, просто $idClean = (int)$_POST['id'];
… будет «заставлять» его целое число, «убивая» все возможные инъекции xss / sql (только для $ idCelan, который я имею в виду)
И, вообще говоря, нет лучшего способа дезинформировать ресурсы; все зависит от того, что должен содержать вход , где он будет храниться и как будет использоваться в будущем.
EDIT : после вашего комментария к middaparka ответ, я полагаю, что $ idClean происходит из формы (возможно, скрытый ввод).
Если вам нравится предотвращать использование этой формы даже maliciuos, я предлагаю вам добавить еще одно скрытое поле с хэшем $ idclean, а затем на странице процесса проверить хэш, чтобы увидеть, изменился ли кто-либо вручную вручную (если вы этого не сделаете уже)
Обычно это неправильный дизайн в управлении пользователями, не знаю, ваше поведение.
Предполагая, что $ _POST ['Image'] является URI, нет. Кто-то может представить URI с использованием схемы javascript: и заставить других людей запускать произвольный JavaScript.
Каков ожидаемый диапазон символов для «изображения» и идентификатора? В то время как экранирование входных данных является хорошей идеей, вы всегда должны проверить, что входные данные содержат только допустимые символы для данного типа данных. например
if (preg_match("/\w(\w|\\.){0,31}/", $imageInput) && preg_match("/\d{1,12}/", $idClean)) { // do database update } else { // invalid input, let the user know! }
Вышеупомянутое регулярное выражение на $ imageInput должно допускать только имя изображения с буквенно-цифровым, подчеркиванием и полной остановкой в нем. Длина от 1 до 32 символов (вы хотели бы сопоставить это с определением базы данных). Никакие другие символы не допускаются. Я сделал регулярное выражение с памятью, простите меня, если экранирование неверно, но принцип использования регулярного выражения для дезинфекции от известного хорошего ввода – это путь.
Безопасность базы данных – это не единственный аспект безопасности, который вам нужно учитывать. Подумайте о межсайтовых сценариях (XSS). Что делать, если пользователь вводит имя изображения как: javascript: alert ('abc'); затем, когда вы отобразите его обратно пользователю, он будет выполняться в своем браузере!
Как уже было сказано, у вас есть проблема с id=xyz
. Но вместо того, чтобы преобразовать его в целое число в php, я передал бы его как строковый литерал по двум причинам:
id
не всегда должен быть целым числом. Шрифт соединения влияет на поведение mysql_real \ escape_string (). Поэтому вы должны передать ресурс соединения в качестве второго параметра в mysql_real \ escape_string ().
Использовать htmlentities () или нет, прежде чем вставлять данные, зависит от того, чего вы хотите достичь. Если вам когда-нибудь понадобятся данные как что-то еще, чем html / utf-8, вам нужно будет его вернуть. Но так как это не совсем связано с безопасностью …. имейте это в виду 😉
$mysql = mysql_connect('..', '..', '..'); //... $query = sprintf(" UPDATE ***** SET image='%s' WHERE id='%s' ", mysql_real_escape_string($imageClean, $mysql), mysql_real_escape_string($id, $mysql) );
О, и кстати: Обязательный намек на подготовленные заявления: http://docs.php.net/pdo.prepared-statements