В PHP, как PDO защищает от SQL-инъекций? Как работают подготовленные заявления?

Я понимаю, что правильный способ защитить db от SQL-инъекции - это использование подготовленных операторов. Я хотел бы понять , как подготовленные заявления защищают мой db.

Во-первых, готовые заявления аналогичны "параметризованным запросам"?

В качестве примера, я вставляю ниже своего кода для вставки нового пользователя в таблицу пользователя. Это безопасно? Как PDO работает, чтобы защитить его? Нужно ли еще что-то делать, чтобы защитить db от инъекций?

В 'Class_DB.php':

class DB {
 private $dbHost;
 private $dbName;
 private $dbUser;
 private $dbPassword;   
 function __construct($dbHost, $dbName, $dbUser, $dbPassword) {
  $this->dbHost=$dbHost;
  $this->dbName=$dbName;
  $this->dbUser=$dbUser;
  $this->dbPassword=$dbPassword;
 }
 function createConnexion() {
  return new PDO("mysql:host=$this->dbHost;dbName=$this->dbName", $this->dbUser, $this->dbPassword);
 }
}

В 'DAO_User.php':

require_once('Class_DB.php');

class DAO_User {
 private $dbInstance;
 function __construct($dbInstance){
  $this->dbInstance=$dbInstance;
 }
 function createUser($user){
  $dbConnection=$this->dbInstance->createConnexion();
  $query=$dbConnection->prepare("INSERT INTO users (userName, hashedPassword, userEmail) VALUES (?,?,?)");
  $query->bindValue(1, $user->userName);
  $query->bindValue(2, $user->hashedPassword);
  $query->bindValue(3, $user->userEmail);
  $query->execute();
 }
}

Спасибо,

JDelage

Ответ 1

Хорошо, я нашел ответ на свой вопрос по этому связанному вопросу: Являются ли подготовленные PDO заявления достаточными для предотвращения SQL-инъекции?

Спасибо Хаиму за указание на это Q мне.

В нетехнических терминах, вот как подготовленные заявления защищают от инъекций:

Когда запрос отправляется в базу данных, он обычно отправляется как строка. Движок db попытается проанализировать строку и отделить данные от инструкций, опираясь на кавычки и синтаксис. Поэтому, если вы отправляете данные пользователя "SELECT * WHERE" "имя таблицы таблицы EQUALS", движок сможет анализировать инструкцию.

Если вы разрешаете пользователю вводить то, что будет отправлено внутри "пользовательских данных", тогда они могут включать в это что-то вроде "..." ИЛИ IF 1 = 1 ERASE DATABASE ". У механизма db будет синтаксический анализ проблем это и возьмет вышеуказанное как инструкцию, а не бессмысленную строку.

Способ PDO заключается в том, что он отдельно отправляет инструкцию (подготовьте ( "INSERT INTO..." ) и данные. Данные отправляются отдельно, четко понимаются как данные и данные. даже попробуйте проанализировать содержимое строки данных, чтобы увидеть, содержит ли она инструкции, и никакой потенциально опасный код-снайпер не рассматривается.

Ответ 2

Вот мой несколько ограниченный взгляд на вопрос...

Готовый оператор скомпилирован на сервере БД с помощью заполнителей для ввода переменной.

Когда вы связываете параметр, вы сообщаете БД, какие значения использовать при выполнении запроса. Затем он передаст значение в скомпилированный оператор.

Разница между параметрами привязки и простой старой инъекцией строк заключается в том, что с первым значением не интерполируется, а скорее назначается. Во время выполнения СУБД обращается к заполнителю и запрашивает значение для использования. Таким образом, нет никаких шансов, чтобы персонажи цитат или другие гадости пробирались в фактическое утверждение.

Ответ 3

Без использования подготовленных операторов вы не можете использовать заполнители (?) в своем запросе.

Вместо этого вам нужно будет включить значение, которое вы хотите вставить непосредственно в оператор SQL. Это приведет к возникновению другого оператора SQL для каждой вставки (плохого для производительности), и если вы не будете осторожны в том, какие строки вы вставляете в оператор, вы также можете получить выражение, которое делает что-то еще, чем то, что вы намеревались (например SQL-инъекция может произойти).

Эта ситуация несколько похожа на функцию Javascript, которая делает некоторый фиксированный код с переменными входными параметрами, вместо вставки входных параметров в источник Javascript и последующего его определения.

Ответ 4

ваш источник защищен от атаки sqli.

он пример и не защищен при выборе пользователя из базы данных.

// example: localhost/user.php?username=admin

$getdata = $_GET['username'];

$dbConnection=$this->dbInstance->createConnexion();
$query=$dbConnection->prepare("SELECT * FROM users WHERE username=".$getdata.");

// PHP simple