user12175925
user12175925

Reputation:

PHP - Is this way I update and select from my database secure?

Recently, I switched to PDO and wanted to ask if is as safe as I do it or not?

(I filter the data before with much filter methods provided by 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");
        }

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

Is this way safe or not?

It's all working fine but I want to know it its safe too

Upvotes: 0

Views: 68

Answers (2)

Michal Hynčica
Michal Hynčica

Reputation: 6169

From the security point of view it should be safe as long as the query in $sql uses param binding properly. If the $sql variable is build like this then your code won't help you.

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

But i can see several other issues with your code.

1) Your try ... catch blocks are useless. When you use PDO::ERRMODE_SILENT the PDO won't raise any exception. Only the $pdo->errorCode or $statement->errorCode properties will be set when error is encountered.

2) You are opening too many connections. I assume that you have the code you've shared in some function that you plan to call like queryDb($sql, $params); That means that every time you will call that function you will create new instance of PDO and open new connection. You might want to move the part that creates PDO instance into the db-config file then use that single instance everytime you are going to create new statement using $pdo->prepare().

3) The use of die. It's common practice to use die or exit when the query goes wrong in examples. But in actual application it would mean the user will see ugly empty page with single sentence saying something went wrong. It's better to throw an exception that will be handled higher in your app. That would let the application to display the page layout with menu and other things even if the requested action failed.

4) You do not set the value to $output variable in your first "Query DB" part of code. Although i'm not sure if you just left it out when copying or if you have it like this in your actual code.

Upvotes: 1

Dharman
Dharman

Reputation: 33375

In regards to SQL injection, as long as you parameterize all inputs and white list all dynamic SQL parts, you should be safe.

However, your code has another serious problem. You are silencing errors. PDO::ATTR_ERRMODE should be set to PDO::ERRMODE_EXCEPTION. But, that would leave your code even in a worse state, as you have die all over the place. Don't catch the exceptions unless you have extremely good reason to do so. Read this article https://phpdelusions.net/pdo#errors

Silencing or displaying errors to the user opens up new vectors for exploitation. That is why the best course of action is to leave them alone. In production system you should have the configuration set to never display errors. They will be securely logged on the server.

Upvotes: 1

Related Questions