简体   繁体   English

PHP Prepared Statement 调用的存储过程中的Prepared Statement

[英]Prepared Statement Inside Stored Procedure Called by PHP Prepared Statement

I'm just wondering if this has any merit from a security standpoint.我只是想知道从安全的角度来看这是否有任何优点。 Say I have a PHP script that needs to get some stuff from the database.假设我有一个需要从数据库中获取一些东西的 PHP 脚本。 Is it safer all around to write it out in PHP and use a prepared statement that way, is it safer to encapsulate everything in a MySQL stored procedure, or can I actually get any security benefit from using a PHP prepared statement to call a MySQL stored procedure that has a prepared statement in it.用 PHP 写出来并以这种方式使用准备好的语句是否更安全,将所有内容封装在 MySQL 存储过程中是否更安全,或者我实际上可以从使用 PHP 准备好的语句调用 MySQL 存储过程中获得任何安全优势吗?包含准备好的语句的过程。 Or does it not really matter as long as I user a prepared statement somewhere?或者,只要我在某处使用准备好的语句,这真的无关紧要吗? Something like the following, but maybe a bit more complex:类似于以下内容,但可能更复杂一些:

PHP: PHP:

require 'path/to/login_utils.php';

try {
    $username = sanitize_validate_username($_POST['username']); // custom cleaning function from login_utils
    $pdo = connect_to_database(); // custom connection function from login_utils
    $select = "SELECT `password`
               FROM `tbl_login`
               WHERE `username`=:username;";
    $prepared = $pdo->prepare($select);
    $prepared->bindValue(":username", $username);
    $prepared->execute();
    $result = $prepared->fetchAll(PDO::FETCH_ASSOC);
    $prepared->closeCursor();
    if (isset($result) && count($result) > 0) {
        $password = $result['password'];
    }
} catch (PDOException $e) {
    die $e->getCode() . ': ' . $e->getMessage();
} finally {
    if (isset($pdo)) {
        unset($pdo);
    }
}
$userpass = $_POST['userpass'];
if (!isset($password) || !password_verify($userpass, $password)) {
    die 'Invalid username and password combo';
}
start_authenticated_session(); // custom session starting function from login_utils
echo 'You have been logged in';
exit;

But what if instead of dynamically making that SELECT in PHP, I put it behind a stored procedure with something like this?但是,如果我不是在 PHP 中动态地进行 SELECT 操作,而是将它放在类似这样的存储过程之后呢?

MySQL: MySQL:

DELIMITER $$
CREATE PROCEDURE usp_GetUserPassword(IN @username VARCHAR(255))
this_proc: BEGIN
    IF @username IS NULL
        THEN LEAVE this_proc;
    END IF;

    DECLARE @password VARCHAR(64);
    PREPARE get_password
    FROM 'SET @password = (
              SELECT `password`
              FROM `tbl_login`
              WHERE `username`=?
          );';
    EXECUTE get_password USING @username;
    DEALLOCATE PREPARE get_password;
    SELECT @password;
END$$
DELIMITER ;

and then called it in my PHP script, replacing the first SELECT with this:然后在我的 PHP 脚本中调用它,将第一个 SELECT 替换为:

$select = "CALL usp_GetUserPassword(:username);";

or something like that, and I continued on to prepare and execute $select in PHP, even though the stored procedure has a prepared statement inside.或者类似的东西,我继续在 PHP 中准备和执行$select ,即使存储过程中有一个准备好的语句。 Would that add any extra security?这会增加任何额外的安全性吗?

Frankly, stored procedures offer no security that you can't get just as easily and effectively by using query parameters in your SQL which you prepare and execute directly from your application code.坦率地说,存储过程不提供安全性,而您无法通过在 SQL 中使用查询参数(直接从应用程序代码准备和执行)来轻松有效地获得这些安全性。

And stored procedures are more difficult to develop in MySQL.并且存储过程在 MySQL 中更难开发。 There's no debugger, there's no package support, there's no standard library, the documentation is thin and difficult to read, there's no persistent compiler, etc.没有调试器,没有包支持,没有标准库,文档很薄且难以阅读,没有持久的编译器等等。

In Microsoft/Oracle/IBM, stored procedures are more mature, and it is traditional to develop large packages of procedures for a project.在微软/甲骨文/IBM中,存储过程比较成熟,为一个项目开发大包的过程是传统。 But in MySQL, I almost never use stored procedures.但是在 MySQL 中,我几乎从不使用存储过程。

For SQL injection prevention, use query parameters.对于 SQL 注入预防,请使用查询参数。 It's easier and just as effective.它更容易,同样有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM