Каковы необходимые и наиболее важные вещи, которые мы должны сделать при проверке, если веб-приложение получает вводимые пользователем данные или параметры? - PullRequest
1 голос
/ 21 октября 2010

Я всегда думаю о проверке любого вида на веб-странице (PHP или ASP, это не имеет значения), но никогда не найду хорошего и точного ответа.

Например, у меня есть некоторый GET -Параметр, который определяет запрос SQL, такой как DESC или ASC. (SQL-Injection?)

Или у меня есть функция комментария для пользователя, где данные также сохраняются в базе данных.

Достаточно ли проверять наличие HTML-тегов внутри данных? Нужно ли выполнять проверку перед добавлением в базу данных или показом на странице?

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

Спасибо.

Ответы [ 3 ]

1 голос
/ 21 октября 2010

Имеете хорошее представление о том, что вы хотите от пользователя.

Вы хотите, чтобы они указали порядок возрастания / убывания?Это перечисление (или логическое значение), а не часть запроса SQL:

$query = "SELECT [...] ORDER BY field " . escape($_GET['sortOrder']); //wrong

Это неправильно независимо от того, сколько вы экранируете и очищаете их строку, потому что это не способ проверки перечисления.Сравните:

if ($_GET['sortOrder'] == 'desc') {
    $ascending = false;
} else {
    $ascending = true;
}

if ($ascending) {
    ...
} else {
    ...
}

... что не требует обсуждения экранирования строк или внедрения SQL, поскольку все, что вам нужно от пользователя, - это ответ да / нет (или возрастание / убывание).

Вы хотите, чтобы они оставили комментарий?Зачем запрещать теги HTML?Что если пользователь захочет ввести HTML-код?

Опять же, вы хотите от них, скажем, «текст ... любой текст с максимальной длиной 1024 символов *».Какое это имеет отношение к SQL или инъекциям?Ничего:

$text = $_POST['commentText'];

if (mb_strlen($text, ENCODING) <= 1024) {
    //valid!
}

Значение в базе данных должно отражать то, что пользователь ввел дословно;не переведено, не сбежало.Допустим, вы удалили весь HTML из комментария.Что происходит, когда вы решаете отправить комментарии куда-нибудь в формате JSON?Вы также удаляете управляющие символы JSON?А как насчет другого формата?Что произойдет, если HTML вводит тег с именем «:)»?Вы обходите свою базу данных, убирая смайлики из всех комментариев?

Ответ - нет, так как вы не хотите HTML-безопасный, JSON-безопасный, какой-то странный формат с улыбкой-безопасныйвход от пользователя.Вам нужен текст длиной не более 1024 символов.Проверьте это.Сохраните это.

Теперь отображаемая часть сложнее.Чтобы отобразить:

<b>I like HTML "tags"

в HTML, вам нужно написать что-то вроде:

&lt;b&gt;I like HTML &quot;tags&quot;

В JSON вы должны сделать:

{ "I like HTML \"tags\" }

ТоВот почему вы должны использовать свои языковые средства для экранирования данных , когда вы их используете .

То же самое, конечно, относится и к SQL, поэтому вы должны экранировать данные при использовании простыхфункции запроса, такие как mysql_query() в PHP.(Параметризованные запросы, которые вы действительно должны использовать, с другой стороны, не требуют экранирования.)

Сводка

Имейте действительно хорошее представление о том, что вы хотите использовать в качестве входных данных, помнячто вам почти никогда не понадобится, скажем, «HTML-безопасный текст».Подтвердите против этого.Escape, когда это необходимо, что означает экранирование HTML при отправке в браузер, SQL при отправке в базу данных и т. Д.


*: Вы также должны определить, что означает здесь «символ».UTF-8, например, может использовать несколько байтов для кодирования кодовой точки.Означает ли «символ» «байт» или «кодовая точка Unicode»?

1 голос
/ 21 октября 2010

Если вы используете PDO, обязательно используйте подготовленные операторы - они автоматически очищают входящие данные.

При использовании функций mysql_ * сначала запустите каждую переменную через mysql_real_escape_string.

Вы также можете выполнить проверку, например, убедиться, что переменная находится в допустимом диапазоне:

$allowed_values = array('name', 'date', 'last_login')
if(in_array($v, $allowed_values)) {
    // now we can use the variable
}
0 голосов
/ 21 октября 2010

Вы говорите о двух видах санации данных. Один из них касается размещения пользовательских данных в вашей базе данных, а другой - размещения пользовательских данных на вашей веб-странице. Для первого вы должны следовать советам Адама. Для более позднего вы должны посмотреть на htmlspecialchars .

Не смешивайте эти два, поскольку они делают две совершенно разные вещи. Для этого санация должна проводиться только в последний момент. Используйте предложение Адама непосредственно перед обновлением базы данных. Используйте htmlspecialchars непосредственно перед отображением данных. не используйте htmlspecialchars для данных перед добавлением их в базу данных.

Возможно, вы захотите осмотреть Stackoverflow, потому что такого рода вопросы задавались и отвечали бесчисленное количество раз в прошлом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...