Является ли этот код php безопасным?

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

Поэтому мой вопрос:

Является ли этот следующий фрагмент кода безопасным?

Я использовал 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, не касаясь этой части кода. id не всегда должен быть целым числом.
  • Диапазон значений (особенно максимальное значение) целого числа php может быть меньше, чем тип определения поля.

Шрифт соединения влияет на поведение 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