循环通过 GET、POST 和 COOKIE 进行清理?

发布于 2024-07-29 18:42:37 字数 405 浏览 6 评论 0原文

考虑到每个人总是担心用户数据(并且确实如此),当您获取它时简单地循环遍历每个外部数组并应用 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;
}

这将使所有数据可以安全地在数据库中使用。 但是,这样做有什么缺点呢?

Considering that everyone is always worried about User Data (And Rightly So), would it be sufficient to simply loop through each external array when you get it, and apply a mysql_real_escape_string().

I'm curious to if this is a bad idea.

Something like:

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

That would make all that data safe to use in databases. But, what are the cons of doing it this way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

我的鱼塘能养鲲 2024-08-05 18:42:38

我认为概括验证和过滤逻辑是一个坏主意。 毕竟,这就是魔术引用背后的想法,现在受到了普遍的谴责。

除此之外,验证字段输入通常涉及很多特定的垃圾。 事实证明,通用规则只是验证的一小部分,尤其是随着应用程序规模和复杂性的增长。

提出一个迷你框架是一个更好的主意,它允许您在同一位置处理通用验证和特定验证。 像这样的东西...

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';

I think it's a bad idea to generalize validation and filtering logic. That was the idea behind magic quotes after all, which is now universally condemned.

Besides that, validating field inputs usually involves a lot of specific junk. Generic rules turn out to be a rather small part of validation, especially as apps grow in size and complexity.

It would be a better idea to come up with a mini framework that allows you to handle both generic and specific validation in the same place. Something like this...

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';
趁年轻赶紧闹 2024-08-05 18:42:38

我认为您实际上正在寻找array_map()。 这消除了对循环的需要。 是的,这对于使请求对数据库安全来说是可以接受的。

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

i think you're actually looking for array_map(). This removes the need for a loop. And yes, this is acceptable for making requests safe for database.

One thing though, you might want to use $_SERVER['REQUEST_METHOD'] here. (unless you're using it to pass in as the param to this function.)

听闻余生 2024-08-05 18:42:37

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

至于清理本身(不仅适用于 SQL),您应该查看 Filter扩展,默认情况下在 PHP 5.2 和 PECL 5.1 中可用。

The main con is if you have to process the input, for example in order to parse markup, you'll have to unescape the input then not forget to re-escape it. Also, it's quite inefficient. Query placeholders are a very good way to prevent SQL injection.

As for sanitization itself (not only for SQL) you should take a look at the Filter extension, available by default in PHP 5.2 and in PECL for 5.1.

墟烟 2024-08-05 18:42:37

在所有超全局变量上应用 mysql_real_escape_string 会给人一种印象:您要么只想在 MySQL 查询中使用它们,要么不知道 mysql_real_escape_string 有何用途。

Applying mysql_real_escape_string on all superglobal variables convey the impression that you either want to use them exclusively in MySQL queries or that you have no clue what mysql_real_escape_string is good for.

怀中猫帐中妖 2024-08-05 18:42:37

缺点:

您可能会忘记还有其他类型的用户输入,因此不清理它们。
当然,还有多余的循环。
而且,我认为数据库清理应该尽可能晚地在将数据输入深度学习中的数据库之前进行。
清理用于演示的数据应该在演示数据之前完成,等等。

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

Cons:

You might forget there are other types of user input and so, not clean them.
And, of course, The excess loops.
And, I think DB cleaning should be done the latest as possible, just before you enter the data into the DB in your DL.
Cleaning data for presentation should be done just before presenting the data, etc.

That said, until you will try this approach, you will never know, as people usualy tend to disagree with approaches they don't use themselves (see above :-) )

只是在用心讲痛 2024-08-05 18:42:37

不要尝试清理数据。 使用带有占位符的查询。 请参阅 bobby-tables.com

Don't try to sanitize data. Use queries with placeholders. See bobby-tables.com

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文