Инъекция SQL - это широко распространенная атака, при проведении которой злоумышленник изменяет параметры веб-страницы (такие как данные в запросе GET/POST или в URL), чтобы ничего не подозревающее приложение выполнило неожиданный SQL-запрос к базе. Это очень опасная уязвимость.
Такая уязвимость возникает, когда SQL-запрос строится вручную с использованием поступивших от пользователя данных. Представим что у нас есть форма в которую мы требуем ввести имя пользователя, чтобы узнать о нем больше. Однако в нашей функции, отвечающей за нахождение пользователя, используется прямой SQL-запрос:
…
user = request.GET['username']
sql = "SELECT * FROM user_data WHERE username = {}".format(user)
…
Подумайте, что произойдет, если злоумышленник введет в поле запроса строку " '' OR 'a'= 'a' ". Результатом станет такой SQL-запрос:
SELECT * FROM user_data WHERE username = '' OR 'a' = 'a';
Поскольку мы допустили возможность добавления в строку произвольных данных, злоумышленник сумел добавить фразу OR, и получившийся в результате запрос возвратит все строки таблицы.
А теперь давайте представим, что случится, если злоумышленник введет в поле строку:
" '' DELETE FROM user_data WHERE 'a' = 'a' "
Тогда получится такой запрос, состоящий из двух SQL-команд:
SELECT * FROM user_data WHERE username = ''
DELETE FROM user_data WHERE 'a' = 'a';
Решение.
Никогда не доверяйте данным, полученным от пользователя, и всегда экранируйте их перед вставкой в SQL-запрос.
API доступа к базе данных в Django выполняет подобную задачу: экранирует все параметры SQL-запроса, применяя соглашения об употреблении кавычек, действующие в используемой СУБД.
Например:
foo.get_list(bar__exact="'' OR 1=1")
Django экранирует входные данные, в результате чего формируется безопасный SQL-запрос. Поэтому, в Django, при обращении к базам данных, правильнее и безопаснее использовать API доступа к БД… Т.е. выборку данных о которой я уже упоминал.