PHP обеспечивает получить против других - PullRequest
0 голосов
/ 02 марта 2011

У меня есть php-файл, который в начале присваивает некоторые переменные из того, что было отправлено с помощью $ _GET.

Затем он выполняет некоторые запросы MySQL, обрабатывает вывод и выводит текст и переменные.

Единственная защита, которую я установил в коде, это mysql_real_escape_string на GET.

Этого достаточно, чтобы предотвратить атаки?

Что еще можно сделать?

Ответы [ 5 ]

5 голосов
/ 02 марта 2011

Ну, вы берете mysql_real_escape_string ужасно неправильно.
Это не ваша вина - это одно из самых странных заблуждений в обществе PHP. Даже на официальной странице справки все неправильно.

Эта функция не имеет ничего общего с защитой чего-либо вообще и переменных GET в частности

Эта функция просто экранирует разделители строк, чтобы разделители строк не могли разбить строку. Таким образом, 2 наиболее важных последствия:

  • не только переменные GET, но и ВСЕ переменные, помещаемые в запрос в кавычках, должны обрабатываться с mysql_real_escape_string(), независимо от их источника или происхождения или возможной опасности
  • это повлияет только на указанные строки. Абсолютно бесполезно использовать эту функцию для любой другой части запроса, например, для переменных предложения LIMIT.

Таким образом, чтобы обезопасить свой SQL-запрос, вы должны следовать всему набору правил , а не просто обманывать "дезинфицировать ваши данные с помощью mysql_real_escape_string".

Вы можете узнать, как защитить свой SQL, из моего предыдущего ответа на аналогичную тему: В PHP при отправке строк в базу данных мне следует позаботиться о недопустимых символах с помощью htmlspecialchars () или использовать регулярное выражение?

обновление
сценарий, чтобы показать, почему mysql_real_escape_string не является серебряной пулей

дается с URL
http://www.example.com/news.php?offset=99999+UNION+SELECT+password+FROM+users+--

код

$offset = mysql_real_escape_string($_GET['offset']);
$sql    = "SELECT title FROM news LIMIT $offset,20";

Результатом станет, если не так помпезно, как за маленькими заколоченными столиками, но несколько не менее пагубно.

0 голосов
/ 02 марта 2011

mysql_real_escape_string защитит вас от SQL-инъекций только тогда, когда вы используете возвращаемое значение в объявлении строки MySQL , например:

'SELECT foo FROM bar WHERE quux="'.mysql_real_escape_string($val).'"'

Он не защитит вас, если вы будете использовать его в любом другом контексте (указав порядок сортировки с помощью ASC / DESC, ограничения строк, имена таблиц / строк и т. Д.). В этом случае вам нужно будет проверить / отфильтровать / санировать значение отдельно.

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

0 голосов
/ 02 марта 2011

Использование этого определенно недостаточно. Это даже не достаточно, когда вы рассматриваете только инъекции SQL. достаточно , когда вы рассматриваете SQL-инъекцию только для строк, но как только у вас есть целое число (скажем, идентификатор), оно выходит из строя:

http://example.com/foo.php?id=10

Проходит:

$q = "SELECT * FROM foo where id = " + mysql_real_escape_string($_GET['id'])

Что приводит к запросу SQL:

SELECT * FROM foo where id = 10

Это легко использовать, например:

http://example.com/foo.php?id=10%3B%20DROP%20TABLE%20foo

Проходит:

$q = "SELECT * FROM foo where id = " + mysql_real_escape_string($_GET['id'])

Что приводит к запросу de SQL:

SELECT * FROM foo where id = 10;DROP TABLE foo

Надеюсь, это проясняет, почему этого недостаточно.

Как вы должны решить это? Определите, какие входные данные разрешены, и убедитесь, что они действительно имеют такую ​​форму, например:

if(preg.match("^[0-9]+$",$_GET['id']){
  // your code here
}else{
  // invalid id, throw error
}

Но лучший способ быть в безопасности (в отношении SQL-инъекций) - использовать подготовленные операторы: http://php.net/manual/en/pdo.prepared-statements.php

0 голосов
/ 02 марта 2011

Нет, существует множество атак, от которых у вас может не быть защиты. Одним из примеров является CSRF. Это большое поле, поэтому я рекомендую прочитать об этом материале на сайте Owasp:

http://www.owasp.org/

0 голосов
/ 02 марта 2011

у вас есть, если переменные get имеют значения с использованием функций isset () и empty ()

...