Подготовленная выписка внутри хранимой процедуры называется PHP Подготовленная выписка - PullRequest
0 голосов
/ 14 января 2020

Мне просто интересно, имеет ли это какое-либо преимущество с точки зрения безопасности. Скажем, у меня есть скрипт PHP, который должен получить кое-что из базы данных. Безопаснее ли все это записывать в PHP и использовать подготовленное утверждение таким образом, безопаснее ли инкапсулировать все в хранимой процедуре MySQL, или же я действительно могу получить какую-либо выгоду от безопасности при использовании подготовленного PHP оператор для вызова MySQL хранимой процедуры с подготовленным оператором. Или это не имеет значения, если я где-то использую готовое заявление? Что-то вроде следующего, но, возможно, немного более сложное:

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;

Но что, если вместо того, чтобы динамически сделать этот SELECT в PHP, я поместил его позади хранимой процедуры с чем-то вроде этого?

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 ;

, а затем вызвал ее в моем PHP сценарии, заменив первый SELECT следующим:

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

или что-то в этом роде, и я продолжил подготовку и выполнение $select в PHP, хотя хранимая процедура имеет подготовленный оператор внутри. Будет ли это добавить дополнительную безопасность?

1 Ответ

2 голосов
/ 14 января 2020

Честно говоря, хранимые процедуры не обеспечивают безопасности, которую вы не можете получить так же легко и эффективно, используя параметры запроса в SQL, который вы готовите и выполняете непосредственно из кода приложения.

И хранимые процедуры сложнее освоить в MySQL. Там нет отладчика, нет поддержки пакетов, нет стандартной библиотеки, документация тонкая и трудная для чтения, нет постоянного компилятора и т. Д. c.

В Microsoft / Oracle / IBM хранимые процедуры более развиты, и традиционно разрабатывается большой пакет процедур для проекта. Но в MySQL я почти никогда не использую хранимые процедуры.

Для SQL предотвращения инъекций используйте параметры запроса. Это проще и эффективнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...