Санитарная обработка PHP / SQL $ _POST, $ _GET и т.д ...? - PullRequest
2 голосов
/ 06 декабря 2011

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

  1. У меня есть форма, в которой нам нужно разрешить людям делать комментарии и заявления, использующие запятые, тильды и т. Д. ... но все жеоставаться в безопасности от атак.

  2. У меня есть люди, которые вводят даты, подобные этой: 13.10.11 мм / дд / гг на английском языке, это можно санировать?

  3. Как я понимаю, как правильно использовать htmlspecialchars(), htmlentities() и real_escape_string()?Я читал сайт php.net и некоторые посты здесь, но мне кажется, что это ситуация, когда все зависит от человека, который читает вопрос, каков правильный ответ.

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

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

Заранее спасибо.

Ответы [ 3 ]

10 голосов
/ 06 декабря 2011

Это очень важный вопрос, и на самом деле он имеет простой ответ в виде кодировок. Проблема, с которой вы сталкиваетесь, заключается в том, что вы используете много языков одновременно. Сначала вы находитесь в HTML, затем в PHP и через несколько секунд в SQL. Все эти языки имеют свои правила синтаксиса.

Следует помнить следующее: строка всегда должна быть в правильном кодировании.

Давайте возьмем пример. У вас есть HTML-форма, и пользователь вводит в нее следующую строку:

I really <3 dogs & cats ;')

После нажатия кнопки отправки эта строка отправляется в ваш PHP-скрипт. Предположим, это делается через GET. Он добавляется к URL-адресу, который имеет собственный синтаксис (например, символ & имеет особое значение), поэтому мы меняем языки. Это означает, что строка должна быть преобразована в правильную кодировку URL. В этом случае браузер делает это, но PHP также имеет функцию urlencode для этого.

В сценарии PHP строка хранится в $_GET, закодированном в виде строки PHP. Пока вы кодируете PHP, это прекрасно. Но теперь давайте поместим строку для использования в запросе SQL. Мы меняем языки и правила синтаксиса, поэтому строка должна быть закодирована как SQL с помощью функции mysql_real_escape_string.

С другой стороны, мы можем захотеть снова отобразить строку для пользователей. Мы получаем строку из базы данных, и она возвращается нам в виде строки PHP. Когда мы хотим встроить его в HTML для вывода, мы снова меняем языки, поэтому мы должны кодировать нашу строку в HTML с помощью функции htmlspecialchars.

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

Что следует избегать (иногда это даже рекомендуется невежественным человеком), так это преждевременное кодирование вашей строки. Например, вы можете применить htmlspecialchars к строке перед тем, как поместить ее в базу данных. Таким образом, когда вы позже извлекаете строку из базы данных, вы можете вставить ее в HTML без проблем. Великолепно звучат? Да, действительно здорово, пока вы не начнете получать билеты в службу поддержки людей, интересующихся, почему их чеки в формате PDF заполнены &amp; &gt; мусором.

В коде:

form.html:

<form action="post.php" method="get">
    <textarea name="comment">
        I really <3 dogs &amp; cats ;')
    </textarea>
    <input type="submit"/>
</form>

URL, который он генерирует:

http://www.example.org/form.php?comment=I%20really%20%3C3%20dogs%20&amp;%20cats%20;')

post.php:

// Connect to database, etc....

// Place the new comment in the database
$comment = $_GET['comment']; // Comment is encoded as PHP string

// Using $comment in a SQL query, need to encode the string to SQL first!
$query = "INSERT INTO posts SET comment='". mysql_real_escape_string($comment) ."'";
mysql_query($query);

// Get list of comments from the database
$query = "SELECT comment FROM posts";

print '<html><body><h2>Posts</h2>';
print '<table>';

while($post = mysql_fetch_assoc($query)) {
    // Going from PHP string to HTML, need to encode!
    print '<tr><td>'. htmlspecialchars($post['comment']) .'</td></tr>';
}

print '</table>';
print '</body></html>'
1 голос
/ 06 декабря 2011

Важно понять, что каждая доступная вам дезинфицирующая функция равна для и когда ее следует использовать.Например, функции экранирования базы данных предназначены для безопасной вставки данных в базу данных и должны использоваться как таковые;но экранирующие HTML-функции предназначены для нейтрализации вредоносного HTML-кода (например, JavaScripts) и обеспечения безопасности вывода данных для просмотра пользователями.Санируйте нужную вещь в нужное время. *

  • Существует два основных подхода, которые вы можете использовать: вы можете санировать HTML, когда получаете его, или можете хранить его точно так же, как вы его получили, и санироватьэто только когда пришло время выводить его пользователю.У каждого из этих методов есть свои сторонники, но второй, вероятно, наименее подвержен проблемам (с первым, что вы будете делать, если в вашей процедуре очистки обнаружен недостаток, и вы обнаружите, что в вашей базе данных недостаточно очищенного содержимого?)

Даты могут быть обработаны с помощью функции разбора даты.В PHP вы можете посмотреть на strtotime () .Ваша цель обычно состоит в том, чтобы взять строковое представление даты и вывести либо объект, представляющий дату, либо другую строку, представляющую ту же дату каноническим способом (то есть: в определенном формате).

0 голосов
/ 07 декабря 2011

Что касается очистки дат, в PHP есть несколько встроенных функций, которые могут быть полезны. Функция strtotime () преобразует практически любой мыслимый формат даты / времени в метку времени Unix, которую затем можно передать в функцию date (), чтобы преобразовать ее в любой формат, который вам нравится.

Например:

$ date_sql = date ("Y-m-d", strtotime ($ _POST ["date"]));

...