Абсолютно чистая / безопасная функция - PullRequest
56 голосов
/ 19 ноября 2010

У меня много пользовательских вводов от $_GET и $_POST ... В данный момент я всегда пишу mysql_real_escape_string($_GET['var']) ..

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

Я думал о функцииНапример, cleanMe($input), и внутри него он должен выполнить mysql_real_escape_string, htmlspecialchars, strip_tags, stripslashes (я думаю, это все, что сделает его чистым и безопасным), а затем вернуть $input.

Так возможно ли это?Создание функции, которая работает для всех $_GET и $_POST, поэтому вы будете делать только это:

$_GET  = cleanMe($_GET);
$_POST = cleanMe($_POST);

Так в вашем коде позже, когда вы работаете, например, с $_GET['blabla'] или $_POST['haha'],они защищены, раздеты и так далее?

Попробовал себя немного:

function cleanMe($input) {
   $input = mysql_real_escape_string($input);
   $input = htmlspecialchars($input, ENT_IGNORE, 'utf-8');
   $input = strip_tags($input);
   $input = stripslashes($input);
   return $input;
}

Ответы [ 7 ]

123 голосов
/ 19 ноября 2010

Идея общей санитарной функции - неработающая концепция.

Существует один правильный метод санитарии для каждой цели. Выполнение их всех без разбора в строке часто приводит к его поломке - исключение фрагмента HTML-кода для запроса SQL приведет к его повреждению для использования на веб-странице и наоборот. Санация должна применяться прямо перед с использованием данных:

  • перед выполнением запроса к базе данных. Правильный метод санитарии зависит от используемой вами библиотеки; они перечислены в Как я могу предотвратить внедрение SQL в PHP?

  • htmlspecialchars() для безопасного вывода HTML

  • preg_quote() для использования в регулярном выражении

  • escapeshellarg() / escapeshellcmd() для использования во внешней команде

  • и т.д.. и т.д.

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

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

7 голосов
/ 19 ноября 2010

Нет смысла просто передавать данные через все эти функции.Все эти функции имеют разные значения.Данные не становятся «чище», вызывая больше escape-функций.

Если вы хотите сохранить пользовательский ввод в MySQL, вам нужно использовать только mysql_real_escape_string.Затем он полностью экранируется для безопасного хранения в базе данных.

EDIT

Также обратите внимание на проблемы, возникающие при использовании других функций.Если клиент отправляет, например, имя пользователя на сервер, а имя пользователя содержит амперсанд (&), вы не хотите вызывать htmlentities перед сохранением его в базе данных, поскольку тогда имя пользователя в базе данных будет&.

6 голосов
/ 19 ноября 2010

Вы ищете filter_input_array(). Однако я предлагаю использовать его только для проверки / очистки бизнес-стиля, а не для фильтрации входных данных SQL.

Для защиты от внедрения SQL используйте параметризованные запросы с mysqli или PDO .

3 голосов
/ 19 ноября 2010

Проблема в том, что что-то чистое или безопасное для одного использования не будет для другого: очистка для части пути, для части запроса MySQL, для вывода html (как html, или в javascript, или во входных значение), для xml могут потребоваться разные вещи, что противоречит.

Но некоторые глобальные вещи можно сделать. Попробуйте использовать filter_input , чтобы получить ввод вашего пользователя. И используйте подготовленные операторы для ваших запросов SQL.

Хотя вместо универсальной функции вы можете создать некоторый класс, который будет управлять вашими входными данными. Примерно так:

class inputManager{
  static function toHTML($field){
    $data = filter_input(INPUT_GET, $field, FILTER_SANITIZE_SPECIAL_CHARS);
    return $data;
  }
  static function toSQL($field, $dbType = 'mysql'){
    $data = filter_input(INPUT_GET, $field);
    if($dbType == 'mysql'){
      return mysql_real_escape_string($data);
    }
  }
}

С такими вещами, если вы видите в своем коде какие-либо $ _POST, $ GET, $ _REQUEST или $ _COOKIE, вы знаете, что вы должны их изменить. И если однажды вам придется изменить способ фильтрации входных данных, просто измените класс, который вы создали.

1 голос
/ 19 ноября 2010

Могу ли я предложить установить "mod_security", если вы используете apache и имеете полный доступ к серверу?!
Это решило большинство моих проблем. Однако не полагайтесь только на одно или два решения, всегда пишите безопасный код;)
UPDATE Нашел этот PHP IDS (http://php -ids.org /); кажется хорошим :) 1006 *

0 голосов
/ 11 июня 2017
<?php
function sanitizeString($var)
{
    $var = stripslashes($var);
    $var = strip_tags($var);
    $var = htmlentities($var);
    return $var;
}

function sanitizeMySQL($connection, $var)
{
    $var = $connection->real_escape_string($var);
    $var = sanitizeString($var);
    return $var;
}
?>
0 голосов
/ 31 января 2016

Я использовал этот массив или получить, отправить

function cleanme(&$array)
{ 
 if (isset($array))
 {
     foreach ($array as $key => $value)
     {
          if (is_array($array[$key]))
          {
           secure_array($array[$key]);
          }
          else 
          {
            $array[$key] = strip_tags(mysql_real_escape_string(trim($array[$key])));
          }
     }
 }
}

Использование:

cleanme($_GET);   
cleanme($_POST);
...