Я использовал блок кода ниже, чтобы якобы остановить SQL-инъекции. Это то, что кто-то показал мне, когда я впервые начал php (что было не так давно)
Я размещаю его на каждой странице, как показано на открытии. Мне интересно, эффективна ли она? Я не знаю, как тестировать для SQL-инъекций
<?php //Start the session session_start(); //=======================open connection include ('lib/dbconfig.php'); //===============This stops SQL Injection in POST vars foreach ($_POST as $key => $value) { $_POST[$key] = mysql_real_escape_string($value); } foreach ($_GET as $key => $value) { $_GET[$key] = mysql_real_escape_string($value); }
Мои типичные запросы на вставку и обновление выглядят так:
$insert = ("'$email','$pw','$company', '$co_description', '$categroy', '$url', '$street', '$suite', '$city', '$state', '$zip', '$phone', '$date', '$actkey'"); mysql_query("INSERT INTO provider (email, pw, company, co_description, category, url, street, suite, city, state, zip, phone, regdate, actkey) VALUES ($insert)") or die ('error ' . mysql_error()); mysql_query("UPDATE coupon SET head='$_POST[head]', fineprint='$_POST[fineprint]', exdate='$exdate', creationdate=NOW() WHERE id='$cid'") or die ('error ' . mysql_error());
Этого недостаточно. 1. Вам не хватает файлов cookie, переменная $ _COOKIE. 2. Если вы используете $ _REQUEST, у вас проблемы. 3. Вы не показывали свои запросы, вы должны указывать каждую переменную с одинарными кавычками '', когда вы помещаете ее в запрос (особенно если данные supposted являются целыми числами, и вы можете подумать, что цитата не нужна в этом случае, но это было бы большой ошибкой). 4. Данные, используемые в вашем запросе, могут поступать из другого источника.
Наилучший способ – использовать привязку данных и автоматическое извлечение данных драйвером, это доступно в расширении PDO.
Пример кода:
$PDO = new PDO('mysql:dbname=testdb;host=127.0.0.1' $user, $password); $stmt = $PDO->prepare("SELECT * FROM test WHERE id=? AND cat=?"); $stmt->execute(array($_GET["id"], $_GET["cat"])); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Вы также можете связывать данные с помощью строковых ключей:
$stmt = $PDO->prepare("SELECT * FROM test WHERE id = :id AND cat = :cat"); $stmt->execute(array(":id" => $_GET["id"], ":cat" => $_GET["cat"]));
Если вы хотите изучить PDO, вы можете найти полезные вспомогательные функции, которые я использую:
http://www.gosu.pl/var/PDO.txt
PDO_Connect(dsn, user, passwd) - connects and sets error handling. PDO_Execute(query [, params]) - only execute query, do not fetch any data. PDO_InsertId() - last insert id. PDO_FetchOne(query [, params]) - fetch 1 value, $count = PDO_FetchOne("SELECT COUNT(*) .."); PDO_FetchRow(query [, params]) - fetch 1 row. PDO_FetchAll(query [, params]) - fetch all rows. PDO_FetchAssoc(query [, params]) - returns an associative array, when you need 1 or 2 cols 1) $names = PDO_FetchAssoc("SELECT name FROM table"); the returned array is: array(name, name, ...) 2) $assoc = PDO_FetchAssoc("SELECT id, name FROM table") the returned array is: array(id=> name, id=>name, ...) 3) $assoc = PDO_FetchAssoc("SELECT id, name, other FROM table"); the returned array is: array(id=> array(id=>'',name=>'',other=>''), id=>array(..), ..)
Каждая из функций, которые извлекают данные, принимает в качестве массива параметров 2-го аргумента (который является необязательным), который используется для автоматической привязки данных к SQL-инъекциям. Его использование было представлено ранее в этом сообщении.
Это несколько эффективно, но это субоптимально – не все данные, которые вы получаете в _GET и _POST, попадают в базу данных. Иногда вам может понадобиться отображать его на странице, и в этом случае mysql_real_escape_string может только повредить (вместо этого вы хотите htmlentities).
Мое правило состоит в том, чтобы немедленно сбежать от него, прежде чем помещать его в контекст, в котором он должен быть экранирован.
В этом контексте вам лучше всего использовать параметризованные запросы – тогда экранирование выполняется автоматически.
Вид.
Функция mysql_real_escape_string
принимает заданную переменную и ускользает от нее для SQL-запросов. Таким образом, вы можете смело добавить строку в запрос типа
$safe = mysql_real_escape_string($unsafe_string); $query = 'SELECT * FROM MyTable WHERE Name LIKE "' . $safe . '" LIMIT 1';
Он НЕ защищает вас от того, что кто-то помещает вредоносный код в этот запрос, который будет отображаться позже (например, XSS или аналогичная атака). Поэтому, если кто-то задает переменную
// $unsafe_string = '<script src="http://dangerous.org/script.js"></script>' $safe = mysql_real_escape_string($unsafe_string); $query = 'UPDATE MyTable SET Name = "' . $safe . '"';
Этот запрос будет выполняться, как вы ожидаете, но теперь на любой странице, где вы печатаете имя этого парня, его сценарий будет выполнен.
Это совершенно НЕПРАВИЛЬНЫЙ подход.
Фактически, вы подражаете печально известным магическим котировкам , что признано плохой практикой. Со всеми его недостатками и опасностями.
это не для того, чтобы исключить SQL-инъекцию, реальный метод escape только добавляет \ к опасному
символы типа «или», поэтому строка с «привет» do'like »станет« привет »,« нравится », так что это
менее опасный
этот метод не всегда полезен; в случае, если вы хотите отобразить содержимое скрытого
переменная на странице, она только уничтожит ее и сделает ее менее читаемой