Нужна помощь в понимании инъекции MySQL - PullRequest
9 голосов
/ 17 октября 2010

От http://www.tizag.com/mysqlTutorial/mysql-php-sql-injection.php Я получил:

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

Я прочитал всю статью, ноУ меня все еще есть некоторые серьезные проблемы, чтобы понять, что это такое и как это можно сделать.

В первом примере, что они на самом деле увидят?

Насколько я понял, если я на самом деле эхо$ name, он будет видеть все имена, потому что это всегда будет «true», правильно ли я?

Другая вещь, которую я не понимаю, - решена ли проблема инъекции MySQL с помощью mysql_real_escape_string (), там естьчтобы быть больше к этому.

Что я действительно не понимаю, так это то, что mysql_real_escape_string () создан для решения этой проблемы, почему это не делается автоматически, я имею в виду, есть ли причина, по которой вы должны добавлять каждыйtime mysql_real_escape_string (), есть ли случаи, когда вы должны его использовать, и поэтому они не делают это автоматически?

Ответы [ 7 ]

10 голосов
/ 17 октября 2010

MySQL не сбежит автоматически, потому что вы строите строку запроса самостоятельно.Например:

$query = 'SELECT * FROM users WHERE name="' . $name . '"';

Вы просто передаете необработанную строку, хранящуюся в $ query, которая открыта для внедрения SQL.Например, если $ name равно [что-то «ИЛИ» 1 = 1], ваша строка запроса в конечном итоге будет иметь вид:

$query = 'SELECT * FROM users WHERE name="something" OR "1=1"

Это вернуло бы каждого пользователя из пользовательской таблицы.Вот почему вам нужно избегать ценностей.Однако, если вы используете PDO, это будет сделано для вас, если вы используете функцию привязки.Это двухэтапный процесс: подготовка запроса, затем «привязка» данных / переменных к заполнителям.В PDO ваша строка запроса будет выглядеть примерно так:

$query = 'SELECT * FROM users WHERE name=":name"';
$bindings = array('name'=>'something');
prepare($query);
execute($bindings);

Тогда все автоматически будет экранировано для вас.

5 голосов
/ 17 октября 2010

Таблицы Бобби содержит краткое описание того, как работает SQL-инъекция. Большую пользу представляют примеры, приведенные на нескольких языках (C #, Java, Perl, PHP и т. Д.)

В случае PHP, во многом зависит, как вы обращаетесь к базе данных. Вы можете извлечь выгоду из использования уровня извлечения базы данных, такого как ADODB , который параметризует запросы.

3 голосов
/ 17 октября 2010

При обсуждении внедрения SQL наиболее распространенным примером является «foo» ИЛИ 1 = 1 », удаляющая всю таблицу или открывающая пароли.Эти инъекции могут быть сорваны, избегая строк.

Однако, есть гораздо более простые инъекции, где mysql_real_escape_string () неэффективен. Например, допустим, у вас есть страница, где пользователь может удалить выбранные записи из вашей базы данных.Распространенной реализацией является создание запроса на удаление записей на основе переменных GET или POST, например:

$row_to_delete = $_POST['id'];
$query = "DELETE FROM table WHERE id=$row_to_delete";

Как вы можете видеть, пользователь может легко опубликовать любой «идентификатор», который он хочет, в этот скрипт,возможно удаление всей таблицы, даже если в строке выполняется mysql_real_escape_string ().Эта та же самая уязвимость может быть использована для предположения , чей «идентификатор» принадлежит администратору и изменяет значения повсюду.Насколько я знаю, единственной защитой является проверка ВСЕХ параметров получения и публикации с любой возможной точки зрения.По сути, не просто проверяйте форму, а проверяйте PARAMETER.

Вы будете удивлены, насколько легко упустить такую ​​простую уязвимость в ваш код.

3 голосов
/ 17 октября 2010

В первом примере по ссылке Tizag запрос выглядит так, как будто автор сценария должен извлечь не более одной строки.Таким образом, учитывая, что каждая строка будет извлечена, наиболее вероятный результат, вероятно, заключается в том, что будет обработана информация для первой возвращенной строки;поскольку в запросе tampered-with нет условия ORDER BY, это может быть пользователь, сохраненный первым в таблице, но, конечно, порядок не определен в SQL, когда отсутствует предложение ORDER BY, так что кто может сказать.Что вы можете сказать, так это то, что, пока таблица не пуста, она будет извлекать информацию о действительном пользователе.

Я не уверен, что вы подразумеваете под словом "if echo $name";переменной $name присваивается значение "timmy" в коде.Думаю, они увидят timmy.Если вы имеете в виду, что если бы вы попытались передать информацию о пользователях, полученную в результате запроса, то что бы они увидели - ну, это зависит от кода, который вы используете.Если вы просматриваете набор результатов, и они использовали SQL-инъекцию для извлечения строк, которые вы не ожидали получить, то они, скорее всего, увидят все строки, включая строки, которые вы не собирались их видеть.Если ваш код просто извлекает информацию из одной строки и воздействует на нее, то они все равно будут видеть одну строку, хотя, опять же, это может быть строка, которую вы не хотели, чтобы они могли достичь.

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

Если вы хотите иметь возможность отказаться от использования mysql_real_escape_string() иНапример, вы можете захотеть использовать параметризованные запросы, которые позволят вам использовать немного более непринужденный подход.Тем не менее, вы все еще должны дать компьютеру понять, какие части вашего запроса являются переменными, которые вы хотите экранировать, хотя, потому что это всего лишь неотъемлемая часть передачи компьютеру того, что вы хотите, чтобы произошло.

1 голос
/ 17 октября 2010

Вы правы, в первом примере человеку, который ввел «плохое» имя, разрешено изменять запрос к базе данных, который вы выполняете, и в этом случае они изменили его, чтобы показать все строки в таблице .

Что касается того, как можно легко предотвратить использование подпрограммы для экранирования специальных символов, вы должны понимать, что строку (или любые данные) можно понимать на разных уровнях. Когда вы принимаете пользовательский ввод и затем используете его для построения запроса к базе данных, вы хотите, чтобы сервер баз данных интерпретировал строку как данные. Однако единственная причина, по которой сервер базы данных делает это, заключается в том, что вы используете специальные символы, такие как одинарные кавычки, поэтому он знает, что знает, где начинается и заканчивается строка. Escape-символы работают, говоря серверу базы данных (или любой другой системе, которая их интерпретирует) не интерпретировать специальные символы как специальные символы, а интерпретировать их как данные, как и остальную часть строки. Таким образом, если в вашей строке есть один из этих специальных символов, его специальная функция будет просто проигнорирована.

А почему это не делается автоматически? Сервер базы данных не может знать, каким данным можно доверять, а какие - нет. Это знает только программист, если им повезет! И вы не можете просто сделать это для всех данных, потому что эти специальные символы (такие как одинарные кавычки) присутствуют по причине - они передают значение серверу базы данных - если вы избегаете всех из них, тогда нет никакого способа передать их значение. Это действительно фундаментальное понятие в компьютерной науке - одна и та же информация может интерпретироваться на разных уровнях в системе, и система может использовать специальные шаблоны данных в этой информации, чтобы обозначать, когда данные должны интерпретироваться на другом уровне.

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

Удачи!

1 голос
/ 17 октября 2010

Насколько я знаю, при создании сайтов вы всегда должны предполагать, что конечный пользователь представляет собой грязную вонючую угрозу, которая хочет сломать ваши вещи. поэтому вы всегда должны чистить свои строки с помощью mysql_real_escape_string();, htmlentities(); и других. код может быть введен в данные вашей формы, которые могут выйти из того, что он делал, вставить новый код и затем полностью контролировать вашу базу данных и, возможно, ваши файловые структуры в зависимости от того, к чему он имеет доступ. это означает, что таблицы, значения, пароли и вся ваша база данных могут быть уничтожены или изменены.

В некоторых случаях вы можете захотеть внедрить код самостоятельно, например, что делать, если вы хотите создать пользовательский интерфейс, который может вводить код в вашу базу данных. (аля phpMyAdmin). может быть, было бы лучше, если бы он как-то автоматически экранировал код, а затем, если вы этого хотели, не экранировал его ... может быть, что-то, что следует обсудить с создателями PHP / mySQL?

Это столько, сколько я знаю. Я надеюсь, что кто-то еще может дать вам больше понимания, чем это. Просто не забывайте всегда очищать возвращаемые значения из форм и ввода пользователя.

0 голосов
/ 01 июня 2012

Функция mysql_real_escape_string () в основном используется для экранирования кавычек, что приводит к ошибке базы данных. Вы не можете зависеть от этой функции, потому что санация очень важна, особенно когда вы вводите данные непосредственно для запроса. Вы можете ссылаться на этот сайт https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

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