PHP - таким образом я обновляю и выбираю из моей базы данных безопасный? - PullRequest
0 голосов
/ 07 октября 2019

Недавно я перешел на 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");
        }

ОБНОВЛЕНИЕ db:

   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("...");
        }

Это безопасно или нет?

Все работает нормально, но я хочу знать, безопасно ли это тоже

Ответы [ 2 ]

1 голос
/ 07 октября 2019

С точки зрения безопасности это должно быть безопасно, если запрос в $ sql правильно использует привязку param. Если переменная $ 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. Обычно в примерах используется die или exit, когда запрос идет не так. Но в реальном приложении это будет означать, что пользователь увидит уродливую пустую страницу с одним предложением, говорящим о том, что что-то пошло не так. Лучше добавить исключение, которое будет обработано выше в вашем приложении. Это позволило бы приложению отображать макет страницы с меню и другими вещами, даже если запрошенное действие не выполнено.

4) Вы не устанавливаете значение переменной $ output в первой части кода «Query DB»,Хотя я не уверен, что вы просто пропустили это при копировании или у вас есть это в вашем реальном коде.

1 голос
/ 07 октября 2019

В отношении внедрения SQL, пока вы параметризуете все входные данные и белый список всех динамических частей SQL, вы должны быть в безопасности.

Однако у вашего кода есть еще одна серьезная проблема. Вы глушите ошибки. PDO::ATTR_ERRMODE должно быть установлено на PDO::ERRMODE_EXCEPTION. Но это оставит ваш код даже в худшем состоянии, поскольку у вас есть die повсюду. Не улавливайте исключения, если у вас нет для этого веских причин. Прочтите эту статью https://phpdelusions.net/pdo#errors

Глушение или отображение ошибок для пользователя открывает новые векторы для эксплуатации. Вот почему лучший способ действий - это оставить их в покое. В производственной системе должна быть установлена ​​конфигурация, чтобы никогда не отображать ошибки. Они будут надежно зарегистрированы на сервере.

...