Mysql
 sql >> база данни >  >> RDS >> Mysql

Замяна на mysql_* функции с PDO и подготвени оператори

Благодаря за интересния въпрос. Ето ви:

Той избягва опасни знаци,

Концепцията ви е напълно грешна
Всъщност "опасните знаци" са мит, няма такива. И mysql_real_escape_string избягва, а просто разделители на низове . От тази дефиниция можете да заключите, че има ограничения – работи само за низове .

въпреки това той все още е уязвим към други атаки, които могат да съдържат безопасни знаци, но могат да бъдат вредни за показването на данни или в някои случаи за злонамерено модифициране или изтриване на данни.

Тук смесвате всичко.
Като говорим за база данни,

  • за низовете НЕ е уязвим. Докато низовете ви са в кавички и екранирани, те не могат "променете или изтрийте данни злонамерено".*
  • за други данни тип данни - да, безполезен е . Но не защото е донякъде "опасно", а просто поради неправилна употреба.

Що се отнася до показваните данни, предполагам, че са offtopic във въпроса, свързан със ЗНП, тъй като ЗНП също няма нищо общо с показването на данни.

избягване на въвеждането на потребителя

^^^ Още една заблуда, която трябва да се отбележи!

  • въведеното от потребителя няма абсолютно нищо общо с избягването . Както можете да научите от предишната дефиниция, трябва да избягвате низове, а не каквото и да е „въведено от потребителя“. И така, отново:

    • имате escape низове, независимо от техния източник
    • безполезно е да се избягват други типове данни, независимо от източника.

Разбрахте смисъла?
Сега се надявам, че разбирате ограниченията на бягството, както и погрешното схващане за „опасните герои“.

Доколкото разбирам, използването на PDO/подготвени оператори е много по-безопасно

Всъщност не.
Всъщност те са четири различни части на заявката, които можем да добавяме към нея динамично:

  • низ
  • число
  • идентификатор
  • ключова дума за синтаксис.

така че можете да видите, че бягството обхваща само един проблем. (но разбира се, ако третирате числата като низове (поставяйки ги в кавички), когато е приложимо , можете също да ги направите безопасни)

докато подготвените изявления обхващат - уф - цели 2 броя! Голяма работа;-)

За другите 2 проблема вижте предишния ми отговор, В PHP, когато изпращам низове към базата данни, трябва ли да се погрижа за незаконните знаци с помощта на htmlspecialchars() или да използвам регулярен израз?

Сега имената на функциите са различни, така че вече няма да работят mysql_query, mysql_fetch_array, mysql_num_rows и т.н.

Това е друга, тежка заблуда на потребителите на PHP , природно бедствие, катастрофа:

Дори когато се използва стар драйвер на mysql, никога не трябва да се използват обикновени API функции в техния код! Човек трябва да ги постави в някаква библиотечна функция за ежедневна употреба! (Не като някакъв магически ритуал, а просто за да направи кода по-кратък, по-малко повтарящ се, устойчив на грешки, по-последователен и четим).

Същото важи и за ЗНП!

Сега отново с вашия въпрос.

но чрез използването им премахва ли това необходимостта от използване на нещо като mysql_real_escape_string?

ДА.

Но мисля, че това е приблизително идеята за това какво трябва да се направи, за да се извлече потребител от база данни

Не за извличане, а за добавяне на каквито и да е данни към заявката !

трябва да посочите дължина след PDO:PARAM_STR, ако не се лъжа

Можеш, но не трябва.

Сега, всичко това безопасно ли е?

По отношение на безопасността на базата данни просто няма слаби места в този код. Тук няма нищо за осигуряване.

за сигурността на показването - просто потърсете в този сайт XSS ключова дума.

Надявам се да хвърля малко светлина по въпроса.

BTW, за дългите вмъквания можете да използвате функцията, която написах някой ден, Вмъкване/актуализиране на помощна функция с помощта на PDO

В момента обаче не използвам подготвени изявления, тъй като предпочитам моите домашно приготвени заместители пред тях, като използвам библиотека споменах по-горе. Така че, за да противодействаме на кода, публикуван от riha по-долу, той би бил толкова кратък, колкото тези 2 реда:

$sql  = 'SELECT * FROM `users` WHERE `name`=?s AND `type`=?s AND `active`=?i';
$data = $db->getRow($sql,$_GET['name'],'admin',1);

Но, разбира се, можете да имате същия код, като използвате и подготвени оператори.

* (yes I am aware of the Schiflett's scaring tales)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Грешка, свързана с only_full_group_by при изпълнение на заявка в MySql

  2. Как да деактивирате проверката на чужд ключ в MySQL

  3. Как да промените НАБОР ОТ СИМВОВЕ (и СЪБОРЯВАНЕ) в цялата база данни?

  4. Как мога да изброя същите идентификационни данни с while цикъл в PHP?

  5. MySQL между клаузата не включва?