【问题标题】:What are ways to improve my PHP data sanitation class?有哪些方法可以改进我的 PHP 数据卫生课程?
【发布时间】:2011-02-16 21:56:20
【问题描述】:

我正在组建一个网站(我们已经在使用 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;

    }
}
?>

【问题讨论】:

  • 根据客户端发送的内容,从 sql 中替换这些常用词似乎会给您带来问题。但是,我建议使用 SQL 抽象层(例如 PDO)并使用它的占位符功能来进行 SQL 清理。 (strip_tags 还是个好主意)

标签: php sql security class sanitization


【解决方案1】:

抱歉,这听起来很刺耳,但你的课程完全被破坏了。

  • 您不应该使用htmlspecialchars 来清理输入,它只对转义输出有用。您不需要对 HTML 进行编码以插入数据库,您也不应该这样做。仅在向浏览器发送输出时使用htmlspecialchars
  • 你不应该从你的输入中剥离标签,你应该不理会它们,当你稍后输出该数据时再次使用 htmlspecialchars 以确保 HTML 标签被转义并且不被浏览器解释
  • 你不应该使用mysql_escape_stringmysql_real_escape_string,你应该使用PDO。如果您正在编写一个新站点,绝对没有理由不正确开始并使用 PDO。 去做
  • 您不应该过滤掉“union”、“select”等,这是愚蠢的。这些词可以以常规英语出现,如果您正确转义 PDO 将为您处理的引号,它们是无害的。

再次,对于这个答案的严厉语气感到抱歉,但放弃整个事情并使用 PDO。这里实际上没有什么可以挽救的。

【讨论】:

  • 没关系,这是我第一次尝试。我会考虑这些观点。过滤这个词在当时似乎是个好主意,但我会检查 PDO。
  • 嗯,我正在看 PDO 的手册,我已经看到有很多我不明白的地方。我必须好好读书。
  • @sto 重要的是验证您的输入。确保数字的东西是数字的,字符串不会太长,必填字段已填充。让 PDO 为数据库处理转义,让htmlspecialchars 为浏览器处理转义。
【解决方案2】:

使用这样的类是个好主意,特别是如果它简化了输入处理。不过有几点我想评论一下:

  • 您应该使用 mysql_real_escape_string 而不是 PHP3 mysql_escape_string。
  • 第一个函数应该被称为html 什么的。 userinput 听起来含糊不清。
  • HTML 转义需要更多参数 htmlspecialchars($str, ENT_QUOTES, "UTF-8") 才能完全安全
  • 将危险的 SQL 关键字列入黑名单并不是一个好主意。它暗示了使用 SQL 查询的错误方法(如果您通过 HTTP 请求接收查询,那就是您的问题)。
    • 您也不应该尝试过滤它们。而是检测到它们,写入错误/安全日志,然后立即 die()。如果试图规避安全性,则尝试对请求进行任何“清理”是没有意义的。

【讨论】:

    【解决方案3】:

    您还可以使用与 PHP 捆绑的filter_* 函数,并为您提供根据特定过滤规则过滤请求参数的机制。

    使用few extra tricks,您甚至可以过滤不同类型数据的数组(感谢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));
    

    这将生成一个完整的数组,其中包含基于 _GET 中的 'manager' 参数的所有必需字段,所有值均已过滤,并且可以选择转义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 2011-11-18
      • 2021-10-12
      • 1970-01-01
      • 2010-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多