Как улучшить мой класс очистки данных PHP? - PullRequest
1 голос
/ 17 февраля 2011

Я собираю сайт (мы уже используем javascript для предварительной проверки на стороне клиента). Однако после того, как надоело писать mysql_real_escape_string через каждую другую строку. Я написал этот класс, который имеет только две функции, в основном предназначенные для очистки данных в пользовательском вводе / sql. Мой вопрос заключается в том, как можно облегчить очистку ввода и улучшить читаемость кода?

<?php 
class Safe {
    function userinput($string){
        $string = strip_tags($string);
        $string = htmlspecialchars($string);
        return $string;
    }
    function sql ($string){
       $sqlstuff = Array("union", "select", "update", "delete", "outfile", "create");
       $string = Safe::str($string);
       $string = mysql_escape_string($string);
       $string = str_ireplace($sqlstuff, "", $string);
       return $string;

    }
}
?>

Ответы [ 3 ]

5 голосов
/ 17 февраля 2011

Извините, это будет звучать грубо, но ваш класс полностью сломан.

  • Не следует использовать htmlspecialchars для очистки ввода, это полезно только для экранирования вывода.Вам не нужно кодировать HTML для вставки в базу данных, как и вы.Только используя htmlspecialchars при отправке вывода в браузер
  • Вы не должны удалять теги из своего ввода, вы должны оставлять их в покое и снова использовать htmlspecialchars, когда вы выводите эти данные позже, чтобы гарантировать, что теги HTMLэкранированный и не интерпретируемый браузером
  • Вы не должны использовать mysql_escape_string или mysql_real_escape_string, вы должны использовать PDO .Если вы пишете новый сайт, у нет абсолютно никаких причин не запускаться правильно и не использовать PDO. Сделайте это .
  • Вы не должны отфильтровывать "объединение", "выбор" и т. Д., Это глупо.Эти слова могут появляться на обычном английском языке, и они безвредны, если вы правильно избегаете кавычек, которые PDO будет обрабатывать для вас.все дело и использовать PDO.Здесь буквально ничего не спасено.
2 голосов
/ 17 февраля 2011

Вы также можете использовать filter _ * функции, которые связаны с PHP и предоставляют вам механизм для фильтрации параметров запроса в соответствии с определенными правилами фильтрации.

С несколькими дополнительными трюками вы можете даже фильтровать массивы различных типов данных (благодаря erisco !).

class sanitizer {

  public function sanitizeValues($values, $filters) {

    $defaultOptions=FILTER_FLAG_NO_ENCODE_QUOTES | FILTER_FLAG_STRIP_LOW | FILTER_NULL_ON_FAILURE;

    $filters=(array)$filters;
    $values=(array)$values;
    foreach ($filters as $key => $filter) {
        if($parts=explode('/', $key)){
            $v=&$values;
            foreach ($parts as $part){
                $v=&$v[$part];
            }
            $filter=(array)$filter;
            $filter[1]=isset($filter[1])?$filter[1]:$defaultOptions;
            $v=filter_var($v, $filter[0], $filter[1]);
            // consider if you really need this here instead of PDO
            // $v=mysql_real_escape_string($v); 
        }
        else{
            $values[$key]=isset($values[$key]) ? filter_var($values[$key], $filter[0], $filter[1]) : null;
        }

    }
    return $values;
  }
}

$manager=sanitizer::sanitizeValues($_GET['manager'], array(
                 'manager/managerID'=>FILTER_VALIDATE_INT,           
                 'manager/username'=>FILTER_SANITIZE_STRING,
                 'manager/name'=>FILTER_SANITIZE_STRING,
                 'manager/email'=>FILTER_SANITIZE_STRING,
                 'manager/phone'=>FILTER_SANITIZE_STRING,
                 'manager/bio'=>FILTER_SANITIZE_STRING,
                 'manager/enabled'=>FILTER_VALIDATE_BOOLEAN,
                 'manager/password'=>FILTER_SANITIZE_STRING));

Это создаст массив со всеми необходимыми полями на основе параметра 'manager' в _GET, со всеми значениями, отфильтрованными и, при необходимости, экранированными.

2 голосов
/ 17 февраля 2011

Хорошей идеей является использование такого класса, особенно если это упрощает обработку ввода.Однако есть несколько моментов, которые я хотел бы прокомментировать:

  • Вы должны использовать mysql_ real_ escape_string вместо PHP3 mysql_escape_string.
  • Первая функция должнаназываться html или что-то.userinput звучит неопределенно и неверно.
  • Для экранирования HTML требуется больше параметров htmlspecialchars($str, ENT_QUOTES, "UTF-8"), чтобы быть абсолютно безопасными
  • Добавление в черный список опасных ключевых слов SQL не является хорошей идеей.Это намекает на неправильный подход к использованию SQL-запросов (если вы получаете запросы через HTTP-запросы, это ваша проблема).
    • Также вам не следует пытаться их фильтровать.Вместо этого обнаружите их, запишите в журнал ошибок / безопасности и сразу же умрите ().Если есть попытка обойти безопасность, нет смысла пытаться «очистить» запрос.
...