PHP-以这种方式更新并从数据库中选择安全吗?

问题描述 投票:0回答:2

最近,我切换到PDO,想问一下是否和我一样安全?

((我以前使用php提供的许多过滤方法过滤数据)

QUERY db:

 include 'path_to_config_file_with_login_creds_for_db.php';
        $options = array(
            PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT,
            PDO::ATTR_PERSISTENT => false,
        );

        try {
            $pdo = new PDO('mysql:host=' . $database_host . ';dbname=' . $database_name . ';charset=utf8mb4', $database_user, $database_pass, $options);
            $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        } catch (PDOException $exception) {
            die("some error message");
        }

        try {
            $statement = $pdo->prepare($sql);
            $statement->execute($bindings);

            $statement->closeCursor();
            return $output;
        } catch (PDOException $stmEx) {
            die("again some error message");
        }

更新数据库:

   include 'again_path_to_config_file_where_creds_to_db.php';
        $options = array(
            PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT,
            PDO::ATTR_PERSISTENT => false,
        );

        try {
            $pdo = new PDO('mysql:host=' . $database_host . ';dbname=' . $database_name . ';charset=utf8mb4', $database_user, $database_pass, $options);
            $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        } catch (PDOException $exception) {
            die("...");
        }

        try {
            $statement = $pdo->prepare($sql);
            $statement->execute($bindings);
            $statement->closeCursor();
        } catch (PDOException $stmEx) {
            die("...");
        }

这种方法是否安全?

一切正常,但我也想知道它的安全性

php pdo prepared-statement
2个回答
1
投票

关于SQL注入,只要您将所有输入参数化并将所有动态SQL部分列入白名单,您就应该是安全的。

但是,您的代码还有另一个严重的问题。您正在沉默错误。 PDO::ATTR_ERRMODE应设置为PDO::ERRMODE_EXCEPTION。但是,这将使您的代码处于更糟糕的状态,因为到处都是die。除非您有充分的理由这样做,否则不要捕获异常。阅读本文https://phpdelusions.net/pdo#errors

向用户静音或显示错误会为利用打开新的载体。这就是为什么最好的行动方针是让他们独自一人。在生产系统中,应将配置设置为从不显示错误。它们将被安全地登录到服务器上。


0
投票

从安全角度来看,只要$ sql中的查询正确使用了参数绑定,它就应该是安全的。如果$ sql变量是这样构建的,那么您的代码将无济于事。

//DO NOT TRY THIS AT HOME
$sql = "SELECT * FROM `users` WHERE user='" . $_POST['user'] . "'";

但是我可以在您的代码中看到其他几个问题。

1]您的try ... catch块无用。当您使用PDO::ERRMODE_SILENT时,PDO不会引发任何异常。遇到错误时,将仅设置$pdo->errorCode$statement->errorCode属性。

2)您打开的连接过多。我假设您已经共享了打算在某些函数中共享的代码,例如queryDb($sql, $params);,这意味着每次调用该函数时,都将创建PDO的新实例并打开新的连接。您可能想将创建PDO实例的部分移到db-config文件中,然后每次使用$pdo->prepare()创建新语句时都使用该单个实例。

3)使用die。在示例中查询出错时,通常使用dieexit。但是在实际应用中,这意味着用户将看到丑陋的空白页面,上面只有一句话,说出了问题。最好抛出一个异常,该异常将在您的应用程序中得到更高的处理。即使请求的操作失败,也可以使应用程序显示带有菜单和其他内容的页面布局。

4)您没有在代码的第一个“查询数据库”部分中将值设置为$ output变量。尽管我不确定在复制时是否只是将其遗漏,或者在实际代码中是否有这样的内容。

© www.soinside.com 2019 - 2024. All rights reserved.