Есть ли где-нибудь функция перехвата, которая хорошо работает для дезинфекции пользовательского ввода для SQL-инъекций и XSS-атак, при этом позволяя использовать определенные типы HTML-тегов?
Как я могу дезинфицировать вводимые пользователем данные с помощью PHP?
Ответы (18)
Распространенное заблуждение, что вводимые пользователем данные можно фильтровать. PHP даже имеет (теперь устаревшую) функцию, которая называется magic-quotes, это основано на этой идее. Ерунда. Забудьте о фильтрации (или очистке, или как там это называют).
Что вам следует делать, чтобы избежать проблем, довольно просто: всякий раз, когда вы встраиваете часть данных во внешний код, вы должны обрабатывать его в соответствии с правилами форматирования этого кода. Но вы должны понимать, что такие правила могут быть слишком сложными, чтобы пытаться соблюдать их все вручную. Например, в SQL правила для строк, чисел и идентификаторов разные. Для вашего удобства в большинстве случаев существует специальный инструмент для такого встраивания. Например, когда вам нужно использовать переменную PHP в запросе SQL, вы должны использовать подготовленный оператор, который позаботится обо всем правильном форматировании / обработке.
Другой пример - HTML: если вы встраиваете строки в разметку HTML, вы должны экранировать ее с помощью htmlspecialchars
. Это означает, что каждый оператор echo
или print
должен использовать htmlspecialchars
.
Третьим примером могут быть команды оболочки: если вы собираетесь вставлять строки (например, аргументы) во внешние команды и вызывать их с помощью _ 5_, тогда вы должны использовать escapeshellcmd
и _ 7_.
Также очень убедительный пример - JSON. Правила настолько многочисленны и сложны, что вы никогда не сможете выполнить их все вручную. Вот почему никогда не следует создавать строку JSON вручную, а всегда использовать специальную функцию, json_encode()
, которая будет правильно форматировать каждый бит данных.
И так далее ...
Единственный случай, когда вам нужно активно фильтровать данные, - это если вы принимаете предварительно отформатированный ввод. Например, если вы разрешите своим пользователям публиковать разметку HTML, которую вы планируете отображать на сайте. Однако вам следует проявить мудрость, чтобы избежать этого любой ценой, поскольку независимо от того, насколько хорошо вы его фильтруете, это всегда будет потенциальная дыра в безопасности.
mysql_real_escape_string
, вы должны быть подключены к базе данных.
- person Ijas Ameenudeen; 16.03.2013
mysql_real_escape_string
устарел. В настоящее время считается хорошей практикой использовать подготовленные операторы для предотвращения внедрения SQL-кода. Так что переключитесь либо на MySQLi, либо на PDO.
- person Marcel Korpel; 05.06.2013
The only case where you need to actively filter data, is if you're accepting preformatted input. Eg. if you let your users post HTML markup, that you plan to display on the site.
, но если вы не дезинфицируете ввод (например, $ _POST), то пользователь всегда может ввести html, верно? Итак ... Здесь вы говорите, что вы должны дезинфицировать каждый ввод пользователя, потому что пользователь может вводить html-код где угодно, если вы его не дезинфицируете. Или я как-то ошибся?
- person Jo Smo; 14.07.2014
why
, это обеспечит мне наилучший уровень безопасности, если я сделаю это как можно позже? Спасибо!
- person Jo Smo; 15.07.2014
<input type="hidden" name="my-val" value="<?= htmlspecialchars($_REQUEST['my-val']); ?>"/>
и URL-адрес http://example.com?my-val=<test>this
, а значение по-прежнему <test>this
в скрытом выражении
- person Si8; 20.04.2018
htmlspecialchars()
и подготовленных операторов достаточно, чтобы очистить ввод пользователя от input
элементов, вставленных в базу данных ?!
- person oldboy; 29.07.2019
<?=
был удален из PHP 7+
- person oldboy; 29.07.2019
Не пытайтесь предотвратить внедрение SQL путем дезинфекции входных данных.
Вместо этого не разрешайте использование данных при создании кода SQL. Используйте подготовленные операторы (т. Е. Параметры в шаблоне запроса), в которых используются связанные переменные. Это единственный способ гарантировать защиту от SQL-инъекций.
Посетите мой веб-сайт http://bobby-tables.com/ для получения дополнительной информации о предотвращении внедрения SQL-кода.
Нет. Вы не можете фильтровать данные в целом без какого-либо контекста, для чего они нужны. Иногда вы хотите использовать SQL-запрос в качестве входных данных, а иногда вы хотите использовать HTML в качестве входных данных.
Вам необходимо отфильтровать входные данные в белом списке - убедитесь, что данные соответствуют некоторой спецификации того, что вы ожидаете. Затем вам нужно избежать его, прежде чем использовать, в зависимости от контекста, в котором вы его используете.
Процесс экранирования данных для SQL - для предотвращения внедрения SQL - сильно отличается от процесса экранирования данных для (X) HTML, чтобы предотвратить XSS.
PHP теперь имеет новые приятные функции filter_input
, например освободить вас от поиска "окончательного регулярного выражения электронной почты" теперь, когда есть встроенный FILTER_VALIDATE_EMAIL
тип
Мой собственный класс фильтра (использует JavaScript для выделения ошибочных полей) может быть инициирован либо запросом ajax, либо публикацией обычной формы. (см. пример ниже) ‹? / ** * Формвалидатор свинины. проверяет поля с помощью регулярных выражений и может их дезинфицировать. Использует встроенные функции PHP filter_var и дополнительные регулярные выражения * @package pork * /
/**
* Pork.FormValidator
* Validates arrays or properties by setting up simple arrays.
* Note that some of the regexes are for dutch input!
* Example:
*
* $validations = array('name' => 'anything','email' => 'email','alias' => 'anything','pwd'=>'anything','gsm' => 'phone','birthdate' => 'date');
* $required = array('name', 'email', 'alias', 'pwd');
* $sanitize = array('alias');
*
* $validator = new FormValidator($validations, $required, $sanitize);
*
* if($validator->validate($_POST))
* {
* $_POST = $validator->sanitize($_POST);
* // now do your saving, $_POST has been sanitized.
* die($validator->getScript()."<script type='text/javascript'>alert('saved changes');</script>");
* }
* else
* {
* die($validator->getScript());
* }
*
* To validate just one element:
* $validated = new FormValidator()->validate('blah@bla.', 'email');
*
* To sanitize just one element:
* $sanitized = new FormValidator()->sanitize('<b>blah</b>', 'string');
*
* @package pork
* @author SchizoDuckie
* @copyright SchizoDuckie 2008
* @version 1.0
* @access public
*/
class FormValidator
{
public static $regexes = Array(
'date' => "^[0-9]{1,2}[-/][0-9]{1,2}[-/][0-9]{4}\$",
'amount' => "^[-]?[0-9]+\$",
'number' => "^[-]?[0-9,]+\$",
'alfanum' => "^[0-9a-zA-Z ,.-_\\s\?\!]+\$",
'not_empty' => "[a-z0-9A-Z]+",
'words' => "^[A-Za-z]+[A-Za-z \\s]*\$",
'phone' => "^[0-9]{10,11}\$",
'zipcode' => "^[1-9][0-9]{3}[a-zA-Z]{2}\$",
'plate' => "^([0-9a-zA-Z]{2}[-]){2}[0-9a-zA-Z]{2}\$",
'price' => "^[0-9.,]*(([.,][-])|([.,][0-9]{2}))?\$",
'2digitopt' => "^\d+(\,\d{2})?\$",
'2digitforce' => "^\d+\,\d\d\$",
'anything' => "^[\d\D]{1,}\$"
);
private $validations, $sanatations, $mandatories, $errors, $corrects, $fields;
public function __construct($validations=array(), $mandatories = array(), $sanatations = array())
{
$this->validations = $validations;
$this->sanitations = $sanitations;
$this->mandatories = $mandatories;
$this->errors = array();
$this->corrects = array();
}
/**
* Validates an array of items (if needed) and returns true or false
*
*/
public function validate($items)
{
$this->fields = $items;
$havefailures = false;
foreach($items as $key=>$val)
{
if((strlen($val) == 0 || array_search($key, $this->validations) === false) && array_search($key, $this->mandatories) === false)
{
$this->corrects[] = $key;
continue;
}
$result = self::validateItem($val, $this->validations[$key]);
if($result === false) {
$havefailures = true;
$this->addError($key, $this->validations[$key]);
}
else
{
$this->corrects[] = $key;
}
}
return(!$havefailures);
}
/**
*
* Adds unvalidated class to thos elements that are not validated. Removes them from classes that are.
*/
public function getScript() {
if(!empty($this->errors))
{
$errors = array();
foreach($this->errors as $key=>$val) { $errors[] = "'INPUT[name={$key}]'"; }
$output = '$$('.implode(',', $errors).').addClass("unvalidated");';
$output .= "new FormValidator().showMessage();";
}
if(!empty($this->corrects))
{
$corrects = array();
foreach($this->corrects as $key) { $corrects[] = "'INPUT[name={$key}]'"; }
$output .= '$$('.implode(',', $corrects).').removeClass("unvalidated");';
}
$output = "<script type='text/javascript'>{$output} </script>";
return($output);
}
/**
*
* Sanitizes an array of items according to the $this->sanitations
* sanitations will be standard of type string, but can also be specified.
* For ease of use, this syntax is accepted:
* $sanitations = array('fieldname', 'otherfieldname'=>'float');
*/
public function sanitize($items)
{
foreach($items as $key=>$val)
{
if(array_search($key, $this->sanitations) === false && !array_key_exists($key, $this->sanitations)) continue;
$items[$key] = self::sanitizeItem($val, $this->validations[$key]);
}
return($items);
}
/**
*
* Adds an error to the errors array.
*/
private function addError($field, $type='string')
{
$this->errors[$field] = $type;
}
/**
*
* Sanitize a single var according to $type.
* Allows for static calling to allow simple sanitization
*/
public static function sanitizeItem($var, $type)
{
$flags = NULL;
switch($type)
{
case 'url':
$filter = FILTER_SANITIZE_URL;
break;
case 'int':
$filter = FILTER_SANITIZE_NUMBER_INT;
break;
case 'float':
$filter = FILTER_SANITIZE_NUMBER_FLOAT;
$flags = FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND;
break;
case 'email':
$var = substr($var, 0, 254);
$filter = FILTER_SANITIZE_EMAIL;
break;
case 'string':
default:
$filter = FILTER_SANITIZE_STRING;
$flags = FILTER_FLAG_NO_ENCODE_QUOTES;
break;
}
$output = filter_var($var, $filter, $flags);
return($output);
}
/**
*
* Validates a single var according to $type.
* Allows for static calling to allow simple validation.
*
*/
public static function validateItem($var, $type)
{
if(array_key_exists($type, self::$regexes))
{
$returnval = filter_var($var, FILTER_VALIDATE_REGEXP, array("options"=> array("regexp"=>'!'.self::$regexes[$type].'!i'))) !== false;
return($returnval);
}
$filter = false;
switch($type)
{
case 'email':
$var = substr($var, 0, 254);
$filter = FILTER_VALIDATE_EMAIL;
break;
case 'int':
$filter = FILTER_VALIDATE_INT;
break;
case 'boolean':
$filter = FILTER_VALIDATE_BOOLEAN;
break;
case 'ip':
$filter = FILTER_VALIDATE_IP;
break;
case 'url':
$filter = FILTER_VALIDATE_URL;
break;
}
return ($filter === false) ? false : filter_var($var, $filter) !== false ? true : false;
}
}
Конечно, имейте в виду, что вам также нужно выполнить экранирование вашего sql-запроса, в зависимости от того, какой тип db вы используете (например, mysql_real_escape_string () бесполезен для sql-сервера). Вероятно, вы захотите обработать это автоматически на соответствующем уровне приложения, например, в ORM. Кроме того, как упоминалось выше: для вывода в html используйте другие специальные функции php, такие как htmlspecialchars;)
Чтобы действительно разрешить ввод HTML с подобными разделенными классами и / или тегами, зависит от одного из специальных пакетов проверки xss. НЕ ЗАПИСЫВАЙТЕ СОБСТВЕННЫЕ РЕГЕКСЫ ДЛЯ РАЗБОРА HTML!
Нет, нет.
Прежде всего, SQL-инъекция - это проблема фильтрации ввода, а XSS - это выход, экранирующий один, поэтому вы даже не сможете выполнять эти две операции одновременно в жизненном цикле кода.
Основные практические правила
- Для запроса SQL привяжите параметры (как в случае с PDO) или используйте встроенную в драйвер функцию экранирования для переменных запроса (например, _ 1_)
- Используйте
strip_tags()
для фильтрации нежелательного HTML - Закройте все остальные выходные данные с помощью
htmlspecialchars()
и помните о втором и третьем параметры здесь.
Чтобы решить проблему XSS, взгляните на HTML Purifier. Он довольно настраиваемый и имеет достойный послужной список.
Что касается атак с использованием SQL-инъекций, убедитесь, что вы проверяете ввод пользователя, а затем запускаете его через mysql_real_escape_string (). Однако эта функция не сможет победить все атаки с использованием инъекций, поэтому важно, чтобы вы проверили данные, прежде чем выгружать их в строку запроса.
Лучшее решение - использовать подготовленные операторы. Их поддерживают библиотека PDO и расширение mysqli.
В PHP 5.2 появилась функция filter_var
.
Он поддерживает множество SANITIZE
, VALIDATE
фильтров.
Методы очистки пользовательского ввода с помощью PHP:
Используйте современные версии MySQL и PHP.
Явно установите кодировку:
$mysqli->set_charset("utf8");
manual$pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF8', $user, $password);
manual$pdo->exec("set names utf8");
manual$pdo = new PDO( "mysql:host=$host;dbname=$db", $user, $pass, array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8" ) );
manual
[deprecated in PHP 5.5.0, removed in PHP 7.0.0].mysql_set_charset('utf8')
Используйте безопасные кодировки:
- Select utf8, latin1, ascii.., dont use vulnerable charsets big5, cp932, gb2312, gbk, sjis.
Используйте пространственную функцию:
- MySQLi prepared statements:
$stmt = $mysqli->prepare('SELECT * FROM test WHERE name = ? LIMIT 1');
$param = "' OR 1=1 /*";
$stmt->bind_param('s', $param);
$stmt->execute(); PDO::quote() - places quotes around the input string (if required) and escapes special characters within the input string, using a quoting style appropriate to the underlying driver:
$pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF8', $user, $password);explicit set the character set
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);disable emulating prepared statements to prevent fallback to emulating statements that MySQL can't prepare natively (to prevent injection)
$var = $pdo->quote("' OR 1=1 /*");not only escapes the literal, but also quotes it (in single-quote ' characters) $stmt = $pdo->query("SELECT * FROM test WHERE name = $var LIMIT 1");PDO Prepared Statements: vs MySQLi prepared statements supports more database drivers and named parameters:
$pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF8', $user, $password);explicit set the character set
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);disable emulating prepared statements to prevent fallback to emulating statements that MySQL can't prepare natively (to prevent injection) $stmt = $pdo->prepare('SELECT * FROM test WHERE name = ? LIMIT 1'); $stmt->execute(["' OR 1=1 /*"]);mysql_real_escape_string[устарело в PHP 5.5.0, удалено в PHP 7.0.0].- mysqli_real_escape_string Экранирует специальные символы в строке для использования в операторе SQL с учетом текущей кодировки подключения. Но рекомендуется использовать подготовленные операторы, потому что они не являются просто экранированными строками, оператор предлагает полный план выполнения запроса, в том числе, какие таблицы и индексы он будет использовать, это оптимизированный способ.
- Используйте одинарные кавычки ('') вокруг ваших переменных внутри вашего запроса.
- MySQLi prepared statements:
Убедитесь, что переменная содержит то, что вы ожидаете:
- If you are expecting an integer, use:
ctype_digit — Check for numeric character(s);
$value = (int) $value;
$value = intval($value);
$var = filter_var('0755', FILTER_VALIDATE_INT, $options); - For Strings use:
is_string() — Find whether the type of a variable is string
Use Filter Function filter_var() — filters a variable with a specified filter:$email = filter_var($email, FILTER_SANITIZE_EMAIL);
more predefined filters
$newstr = filter_var($str, FILTER_SANITIZE_STRING); - filter_input() — Gets a specific external variable by name and optionally filters it:
$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
- preg_match () - выполняет сопоставление регулярного выражения;
- Напишите свою собственную функцию проверки.
- If you are expecting an integer, use:
Один из приемов, который может помочь в конкретных обстоятельствах, когда у вас есть страница типа /mypage?id=53
и вы используете id в предложении WHERE, заключается в том, чтобы убедиться, что id определенно является целым числом, например:
if (isset($_GET['id'])) {
$id = $_GET['id'];
settype($id, 'integer');
$result = mysql_query("SELECT * FROM mytable WHERE id = '$id'");
# now use the result
}
Но, конечно, это отсекает только одну конкретную атаку, поэтому прочтите все остальные ответы. (И да, я знаю, что приведенный выше код не очень хорош, но он показывает конкретную защиту.)
$id = (int)$_GET['id']
и $que = sprintf('SELECT ... WHERE id="%d"', $id)
тоже хорошо
- person vladkras; 21.11.2016
if (isset($_GET['id']) { if !( (int) $_GET['id'] === intval($_GET['id'] ) ) { throw new \InvalidArgumentException('Invalid page id format'); } /* use a prepared statement for insert here */ };
может вам подойти. Я предпочитаю вообще не обращаться к базе данных, если могу определить, что параметр определенно недействителен на основе известной схемы, которой он передается.
- person mopsyd; 04.01.2021
Здесь вы описываете две отдельные проблемы:
- Очистка / фильтрация вводимых пользователем данных.
- Экранирование вывода.
1) Пользовательский ввод всегда должен рассматриваться как плохой.
Использование подготовленных операторов и / или фильтрация с помощью mysql_real_escape_string, безусловно, является обязательным. PHP также имеет встроенный filter_input, который является хорошим местом для начала.
2) Это большая тема, и она зависит от контекста выводимых данных. Для HTML есть такие решения, как htmlpurifier. как правило, всегда избегайте всего, что вы выводите.
Обе проблемы слишком велики, чтобы обсуждать их в одном посте, но есть много постов, в которых подробно рассказывается:
Нет функции перехвата, потому что необходимо решить несколько проблем.
- Внедрение SQL. Сегодня, как правило, каждый проект PHP должен использовать подготовил операторы через объекты данных PHP (PDO) в качестве наилучшей практики, предотвращая ошибку из-за случайной цитаты, а также являясь полнофункциональным решением против внедрения. Это также самый гибкий и безопасный способ доступа к вашей базе данных.
Ознакомьтесь с (Единственно правильным) учебным пособием по PDO почти все, что вам нужно знать о PDO. (Искренняя благодарность ведущему участнику SO, @YourCommonSense, за этот замечательный ресурс по этой теме.)
- XSS - дезинфекция данных на пути к…
HTML Purifier существует уже давно и до сих пор активно обновляется. Вы можете использовать его для дезинфекции вредоносного ввода, сохраняя при этом широкий и настраиваемый белый список тегов. Отлично работает со многими редакторами WYSIWYG, но в некоторых случаях может быть затруднительно.
В других случаях, когда мы вообще не хотим принимать HTML / Javascript, я нашел эту простую функцию полезной (и прошел несколько проверок XSS):
/* Prevent XSS input */ function sanitizeXSS () { $_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING); $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING); $_REQUEST = (array)$_POST + (array)$_GET + (array)$_REQUEST; }
- XSS - дезинфекция данных на выходе ... если вы не гарантируете, что данные были должным образом продезинфицированы перед добавлением их в свою базу данных, вам нужно будет дезинфицировать их перед отображением для вашего пользователя, мы можем используйте эти полезные функции PHP:
- Когда вы вызываете
echo
илиprint
для отображения значений, введенных пользователем, используйтеhtmlspecialchars
, если только данные был должным образом продезинфицирован, и ему разрешено отображать HTML. json_encode
- безопасный способ передачи пользовательских значений из PHP в Javascript
- Вызываете ли вы внешние команды оболочки с помощью
exec()
или _ 7_ или к _ 8_ оператор? Если да, то помимо внедрения SQL и XSS у вас может возникнуть дополнительная проблема, которую необходимо решить, пользователи, выполняющие вредоносные команды на вашем сервере. Вам необходимо использоватьescapeshellcmd
, если вы хотите избежать всей команды ИЛИescapeshellarg
, чтобы избежать отдельных аргументов.
mb_encode_numericentity
обсуждается в ссылке htmlspecialchars
на # 3 XSS
- person webaholik; 03.10.2019
Если вы используете PostgreSQL, ввод из PHP может быть экранирован с помощью pg_escape_literal()
$username = pg_escape_literal($_POST['username']);
Из документации:
pg_escape_literal()
экранирует литерал для запроса базы данных PostgreSQL. Он возвращает экранированный литерал в формате PostgreSQL.
Самый простой способ избежать ошибок при очистке ввода и экранировании данных - использовать PHP-фреймворк, например Symfony, Nette и т. д. или часть этой структуры (механизм создания шаблонов, уровень базы данных, ORM).
Механизм создания шаблонов, такой как Twig или Latte, по умолчанию имеет экранирование вывода - вам не нужно решать вручную, если вы правильно экранировали вывод в зависимости от контекста (часть веб-страницы HTML или Javascript).
Framework автоматически очищает ввод, и вы не должны использовать переменные $ _POST, $ _GET или $ _SESSION напрямую, а через такие механизмы, как маршрутизация, обработка сеанса и т. Д.
А для уровня базы данных (модели) существуют ORM-фреймворки, такие как Doctrine, или оболочки вокруг PDO, такие как Nette Database.
Вы можете узнать больше об этом здесь - Что такое программная среда?
Просто хотел добавить, что по поводу экранирования вывода, если вы используете php DOMDocument для вывода html, он будет автоматически экранирован в правильном контексте. Атрибут (value = "") и внутренний текст ‹span› не равны. Чтобы обезопасить себя от XSS, прочтите следующее: Памятка по предотвращению XSS OWASP
Вы никогда не дезинфицируете ввод.
Вы всегда дезинфицируете вывод.
Преобразования, которые вы применяете к данным, чтобы сделать их безопасным для включения в инструкцию SQL, полностью отличаются от тех, которые вы запрашиваете для включения в HTML, полностью отличаются от тех, которые вы запрашиваете для включения в Javascript, полностью отличаются от тех, которые вы запрашиваете для включения в LDIF. полностью отличаются от тех, которые вы применяете для включения в CSS, полностью отличаются от тех, которые вы применяете для включения в электронное письмо ...
Обязательно проверять ввод - решить, нужно ли вы должны принять его для дальнейшей обработки или сообщить пользователю, что это неприемлемо. Но не применяйте никаких изменений к представлению данных, пока они не покинут территорию PHP.
Давным-давно кто-то пытался изобрести универсальный механизм для экранирования данных, и в итоге мы получили magic_quotes, который не экранировал данные для всех целевых объектов и приводил к другой установке, требующей для работы другого кода.
Используйте это обрезание пустого пространства и удаление непечатаемого символа
$data = trim(preg_replace('/[[:^print:]]/', '', $data));
Существует расширение фильтра (howto-link, manual), который довольно хорошо работает со всеми переменными GPC. Однако это не волшебная штука, вам все равно придется ее использовать.
Никогда не доверяйте пользовательским данным.
function clean_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
Функция trim()
удаляет пробелы и другие предопределенные символы с обеих сторон строки.
Функция stripslashes()
удаляет обратную косую черту
Функция htmlspecialchars()
преобразует некоторые предопределенные символы в объекты HTML.
Предопределенные символы:
& (ampersand) becomes &
" (double quote) becomes "
' (single quote) becomes '
< (less than) becomes <
> (greater than) becomes >
clean_input
? Зачем вам убирать косые черты?
- person Dharman; 14.07.2019
stripslashes()
. Вы также можете увидеть, что делают сотрудники WordPress.
- person bam; 12.10.2020
select * from users where name='$name'
, тогда не имеет значения, используете ли вы PDO, MySQLi или MySQL. Вы все еще в опасности. Вы должны использовать параметризованные запросы или, если необходимо, использовать механизмы экранирования ваших данных, но это гораздо менее предпочтительно. - person Andy Lester   schedule 20.12.2013