|
Оглавление
|
SQL инъекция — это стандартная уязвимость, в которой атакующая сторона изменяет параметры веб страницы (такие как GET/POST данный или URL) для внедрения определённых кусков SQL запроса, которые наивное веб приложение выполняет напрямую над своей базой данных. Вероятно, это наиболее опасная и, к сожалению, наиболее часто встречающаяся уязвимость. Данная уязвимость чаще всего проявляется, когда SQL собирается вручную на основе пользовательского ввода. Например, представим создание функции для получения списка с контактной информацией с помощью страницы поиска. Для защиты данных об адресах электронной почты от спаммеров, мы будем требовать от пользователя ввода чьего-нибудь имени и будет предоставлять адрес для введённого имени: def user_contacts(request):
user = request.GET['username']
sql = "SELECT * FROM user_contacts WHERE username = '%s';" % username
# execute the SQL here...
ЗамечаниеВ данном примере, и в других подобных «не делай так» примерах, мы намеренно опустим большую часть кода, необходимого для работоспособности описываемых функций. Мы не желаем, чтобы кто-нибудь использовал такой код вне контекста данной главы.
И хотя такой код не выглядит опасным, он таковым является. Во-первых, наша попытка защитить весь наш список адресов электронной почты провалится из-за хитро составленного запроса. Подумайте о том, что может случиться, если атакующий введёт ' OR 'a'='a в поле запроса. В этом случае, будет сконструирован следующий запрос: SELECT * FROM user_contacts WHERE username = '' OR 'a' = 'a';
Так как мы не проверяем введённую строку на наличие SQL команд, атакующий добавил выражение OR и это приведёт к выдаче всех записей из соответствующей таблицы. Однако, существует как минимум ещё одна опасность. Представьте, что может случиться, если атакующий введёт '; DELETE FROM user_contacts WHERE 'a'='a'. Вот так будет выглядеть сконструированный запрос: SELECT * FROM user_contacts WHERE username = ''; DELETE FROM user_contacts WHERE 'a' = 'a';
Ой! А куда делся наш список контактов? Несмотря на то, что данная проблема является не очевидной, решение для неё будет простым: никогда не доверяйте пользовательским данным и всегда экранируйте всё, что вы используете при конструировании SQL запроса. Всё это Django делает на уровне API для работы с базой данных. Он автоматически экранирует все специальные SQL параметры, учитывая соглашение об использовании кавычек для используемого вами сервера баз данных (т.е., PostgreSQL или MySQL). Например, в данном вызове API: foo.get_list(bar__exact="' OR 1=1") Django выполнит соответствующее экранирование и результирующий оператор будет выглядеть так: SELECT * FROM foos WHERE bar = '\' OR 1=1' т.е., очень безобидно. Это поведение характерно для всего API с некоторыми исключениями:
В каждом из этих случаев, несложно защитить себя от ошибок. Надо просто использовать привязку переменных вместо конструирования запросов. Таким образом, предыдущий пример должен быть переписан так: from django.db import connection
def user_contacts(request):
user = request.GET['username']
sql = "SELECT * FROM user_contacts WHERE username = %s;"
cursor = connection.cursor()
cursor.execute(sql, [user])
# ... do something with the results
Низкоуровневый метод
К сожалению, вы не можете свободно использовать привязку
переменных. Например, нельзя таким способом определять
идентификаторы (т.е., имя таблицы или полей
таблиц). Следовательно, если вам потребуется динамически
создать список таблиц по, скажем, содержимому переменной
|
Увидели ошибку?
Выделите её мышкой и нажмите
-
Обработано:
1049
49
130
71
Версия книги
1.0
2.0
Версия 2.0 в процессе перевода!
Мой луч
Многообразие света
Полезное
Актуальные вакансии,
Python работа
для python-разработчиков.
Скачать в формате
CHM от 2 сентябряЗаказать PDF файл можно через почту, чат, джаббер. Всего 2WMZ. Содержимое точно соответствует содержимому сайта. Чем чаще заказываете — тем больше перевожу. Русская группа
Ускорить процесс перевода!
R130494980980
Z425285133788 E112528079659 U327380922061 Книга помогла реализовать:
|
| © 2008-2009 Ruslan Popov @ gmail.com | Powered by Django 1.1 beta 1 SVN-11114 |