2010-02-25 2 views
4

Я знаю, что должен использовать подготовленный оператор, но мой следующий проект будет использовать подготовленный оператор, мне просто нужно закончить это простое небольшое приложение.Этот код 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'); 
} 

Спасибо за вашу помощь.

p.s Если бы вы могли предложить что-то добавить, это было бы здорово.

+3

думать, что происходит, когда $ idclean = "1 ИЛИ 1 = 1" – Piskvor

+0

& Piskvor следует использовать if (cytpe_digit) для $ idClean? –

+1

@Oliver Bayes-Shelton: Предполагая, что 'id' является целым числом, я бы пошел (int) $ idClean – Piskvor

ответ

3

Вы должны применять только экранирование объекта в точке вывода - нет значения для экранирования данных до вставки базы данных. Тем не менее, вы делаете правильные вещи с точки зрения mysql_real_escape_string.

Кроме того, поскольку @Piskvor говорит, что существует потенциальная проблема с переменной idClean. (Является ли это быть брошенным к междунар, например?)

Вы можете использовать следующий, например:

mysql_real_escape_string(intval($idClean)) 
+0

Не могли бы вы немного объяснить, что происходит с исчезновением объекта? Что мне делать вместо этого? –

+0

Могу ли я использовать: // Id изменить если (ctype_digit ($ _ POST [ 'свидетельство'])) { \t $ idInput = $ _POST [ 'testmonial']; \t $ idClean = htmlentities ($ idInput, ENT_QUTOES, 'UTF-8'); } –

+1

-1 Вам не нужно запускать mysql_real_escape_string() на целое число, вы избыточно. – rook

2

$ idClean, где происходят из?

другой $ _POST? он должен быть целым числом, не так ли?

не делает HTML санитарным на нем, только $idClean = (int)$_POST['id']; ... будет «сила», чтобы быть целым, «убивая» все возможные инъекции XSS/SQL (только для $ idCelan я имею в виду)

И вообще говорящих, нет ни одного наилучшим образом для дезинфекции входов; все зависит от , что вход должен содержать, где будет сохранено и как будет в будущем.

EDIT: после вашего ответа на middaparka ответ, я полагаю, что $ idClean исходит из формы (возможно, скрытого ввода).

Если вы хотите предотвратить использование maliciuos этой формы, я предлагаю вам добавить еще одно скрытое поле с $ idclean hashed, а затем на странице процесса проверить хэш, чтобы увидеть, изменился ли кто-либо вручную (если вы не делаете этого уже)

Это, как правило, неправильный дизайн в управлении пользователями, не знаю, является ли ваше поведение.

1

Предполагая, что $ _POST ['Image'] является URI, нет. Кто-то может представить URI с использованием схемы javascript: и заставить других людей запускать произвольный JavaScript.

+0

нет $ _POST ['Изображение'] является только filename.extension –

4

Зависит от того, насколько чист ваш $idClean.

WHERE id=" . mysql_real_escape_string($idClean) . " 

mysql_real_escape_string only prepends backslashes to \x00, \n, \r, \, ', " and \x1a, но это не остановит злоумышленника с помощью

$idClean = "1 OR 1=1 AND POSSIBLY OTHER SQL STATEMENTS" 

Вместо mysql_real_escape_string вы должны просто преобразовать его в междунар.

+0

+1 очень хорошо. Вы совершенно правы. За исключением того, что введенный sql недействителен. Злоумышленник будет использовать подвыбор, чтобы использовать это. – rook

0

Каков ожидаемый диапазон символов для «изображения» и идентификатора? В то время как экранирование входных данных является хорошей идеей, вы всегда должны проверить, что входные данные содержат только допустимые символы для данного типа данных. например

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'); затем, когда вы отобразите его обратно пользователю, он будет выполняться в своем браузере!

0

Как уже было сказано, у вас есть проблема с id=xyz. Но вместо того, преобразовав его в целое число в PHP я бы передать его в качестве строкового литерала, тоже, по двум причинам:

  • Вы можете изменить тип поля ид, не касаясь этой конкретной части кода. Значение id не всегда должно быть целым числом.
  • Диапазон значений (особенно максимальное значение) целого числа php может быть меньше, чем тип определения поля.

connection charset влияет на поведение 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

Смежные вопросы