Reputation:
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
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
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