代码之家  ›  专栏  ›  技术社区  ›  Tyler Carter

循环通过get、post和cookie进行消毒?

  •  0
  • Tyler Carter  · 技术社区  · 15 年前

    考虑到每个人都在担心用户数据(正确地说是这样),当你得到每个外部数组时,仅仅循环它,并应用一个mysql_real_escape_string()就足够了吗?

    我很好奇这是不是个坏主意。

    类似:

    function getExternalData($type='GET')
    {
        $type = strtoupper($type);
        $data = $_$type;
        foreach($data as $key => $value)
        {
            $clean[$key] = mysql_real_escape_string($value);
        }
        return $clean;
    }
    

    这将使数据库中使用的所有数据都安全。但是,这样做的缺点是什么?

    6 回复  |  直到 15 年前
        1
  •  2
  •   Josh Davis    15 年前

    主要的缺点是,如果您必须处理输入,例如为了解析标记,您必须取消对输入的scape,然后不要忘记重新转义它。而且,它效率很低。查询占位符是防止SQL注入的非常好的方法。

    至于卫生处理本身(不仅仅是SQL),您应该看看 Filter extension ,默认情况下在php 5.2和pecl中用于5.1。

        2
  •  2
  •   Gumbo    15 年前

    应用 mysql_real_escape_string 在所有的超全局变量上,您要么希望在MySQL查询中专门使用它们,要么根本不知道是什么 mysql_real_escape_字符串 是有益的。

        3
  •  1
  •   Itay Moav -Malimovka    15 年前

    欺骗:

    您可能会忘记还有其他类型的用户输入,因此,不要清除它们。
    当然,还有多余的循环。
    而且,我认为数据库清理应该是最新的,在您将数据输入到您的DL中的数据库之前。
    在展示数据等之前,应完成展示数据的清理工作。

    也就是说,除非你尝试这种方法,否则你永远不会知道,因为人们通常会不同意他们自己不使用的方法(见上文-)。

        4
  •  1
  •   Andy Lester    15 年前

    不要试图清理数据。使用带占位符的查询。见 bobby-tables.com

        5
  •  1
  •   bytebrite    15 年前

    我认为推广验证和过滤逻辑是个坏主意。毕竟,这就是《魔幻语录》背后的想法,现在这一点已被普遍谴责。

    除此之外,验证字段输入通常涉及许多特定的垃圾。一般规则在验证中只占很小的一部分,特别是随着应用程序的规模和复杂性的增加。

    最好设计一个迷你框架,允许您在同一个地方处理通用和特定的验证。像这样的…

    class BrokenRules extends Exception {
        protected $errors;
        function __construct($errors) {
            $this->errors = $errors;
        }
        function getErrors() {
            return $this->errors;
        }
    }
    
    class Foo {
        protected $db;
        function __construct(PDO $db) {
            $this->db = $db;
        }
        function loadNew() {
            return array('bar' => 'new foo', 'baz' => 5);
        }
        function loadById($id) {
            $stmt = $this->db->prepare('SELECT * FROM foo WHERE id = ?');
            $stmt->bindValue(1, $id, PDO::PARAM::INT);
            $stmt->execute();
            return $stmt->fetch();
        }
        function save($data) {
            return isset($data['id']) ? $this->update($data) : $this->insert($data);
        }
        protected function validateForInsert($data) {
            if ((int)$data['baz'] <= 3) $errors['baz'][] = 'Baz must be greater than 3';
            if (isset($errors)) throw new BrokenRules($errors);
        }
        protected function validateForUpdate($data) {
            // TODO: validateForUpdate
        }
        protected function insert($data) {
            $this->validateForInsert($data);
            $stmt = $this->db->prepare('INSERT INTO foo (x, y) VALUES (?, ?)');
            $stmt->bindValue(1, $data['bar'], PDO::PARAM_STR);
            $stmt->bindValue(2, $data['baz'], PDO::PARAM_INT);
            $stmt->execute();
            return $this->db->lastInsertId();
        }
        protected function update($data) {
            $this->validateForUpdate($data);
            $stmt = $this->db->prepare('UPDATE foo SET x = ?, y = ? WHERE id = ?');
            $stmt->bindValue(1, $data['bar'], PDO::PARAM_STR);
            $stmt->bindValue(2, $data['baz'], PDO::PARAM_INT);
            $stmt->bindValue(3, $data['id'], PDO::PARAM_INT);
            $stmt->execute();
            return $data['id'];
        }
    }
    
    try {
        $foo = new Foo($pdo);
        if ($_POST) {
            $id = $foo->save($_POST);
            redirect("edit_foo.php?id=$id");
        } else if (isset($_GET['id'])) {
            $data = $foo->loadById($_GET['id']);
        } else {
            $data = $foo->loadNew();
        }
    } catch (BrokenRules $e) {
        $errors = $e->getErrors();
    }
    
    include 'templates/foo.php';
    
        6
  •  0
  •   helloandre    15 年前

    我想你真的在找 array_map() . 这样就不需要循环。是的,这对于保证数据库请求的安全是可以接受的。

    但有一件事,你可能想用 $_SERVER['REQUEST_METHOD'] 在这里。(除非您使用它作为该函数的参数传入。)