В предыдущей статье мы уже говорили о сути уязвимостей SQL-инъекций, вызванных неправильным кодированием программистами. Теперь мы продолжим говорить о том, как правильно кодировать, чтобы не подвергнуться атаке SQL-инъекцией. Прежде чем говорить об этом. проблема Давайте сначала посмотрим на фрагмент кода:
Скопируйте код кода следующим образом:
dim sql_injdata,SQL_inj,SQL_Get,SQL_Data,Sql_Post
SQL_injdata = '|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare
SQL_inj = разделение (SQL_Injdata, |)
Если Request.QueryString<> Тогда
Для каждого SQL_Get в Request.QueryString
Для SQL_Data=0 к Ubound(SQL_inj)
если instr(Request.QueryString(SQL_Get),Sql_Inj(Sql_DATA))>0 Тогда
Response.Write <Script Language=javascript>alert('Система защиты от внедрения SQL подсказывает, пожалуйста, не пытайтесь выполнить внедрение снова!'); History.back(-1)</Script>
Ответ.конец
конец, если
следующий
Следующий
Конец, если
Если Запрос.Форма<> Тогда
Для каждого Sql_Post в Request.Form
Для SQL_Data=0 к Ubound(SQL_inj)
если instr(Request.Form(Sql_Post),Sql_Inj(Sql_DATA))>0 Тогда
Response.Write <Script Language=javascript>alert('Система защиты от внедрения SQL подсказывает, пожалуйста, не пытайтесь выполнить внедрение снова!'); History.back(-1)</Script>
Ответ.конец
конец, если
следующий
следующий
конец, если
Это фрагмент кода защиты от внедрения ASP, который широко популярен в Интернете. Идея состоит в том, чтобы проверять данные, отправленные методами Post и Get, а также предотвращать SQL-инъекцию путем фильтрации конфиденциальных символов, таких как Insert, Update и And. и т. д. Теоретически, если мы отфильтруем достаточное количество символов, мы определенно можем гарантировать, что мы не будем атакованы SQL-инъекцией, но будьте осторожны. Прочтите этот код и обратите внимание на то, как он оценивается с помощью функции instr. То есть, если я хочу фильтровать символ and, фильтруется не только слово And, но и все слова. содержащие и. Все слова со следующими комбинациями символов были отфильтрованы, например, остров, материк, рука... Если бы эти символы были отфильтрованы, захотел бы кто-нибудь их использовать? Поэтому этот метод фильтрации деликатных символов вообще бессмысленен. Что меня удивляет, так это то, что такая фигня вообще выложена в Интернет как классика. Я действительно потерял дар речи.
Некоторые люди говорят, что атаки с использованием SQL-инъекций вызваны объединением строк SQL-запроса, поэтому использование хранимых процедур без объединения строк SQL-запроса может защитить вас от атак с использованием SQL-инъекций. Верно ли это? Не обязательно, давайте рассмотрим пример атаки с использованием хранимой процедуры.
Код хранимой процедуры dt_GetNews выглядит следующим образом:
СОЗДАТЬ ПРОЦЕДУРУ dt_GetNews
@newstype целое
КАК
выберите * из новостей, где newstype=@newstype
ИДТИ
Код вызова:
<%
тусклое соединение
установить adoconnection=server.createobject(adodb.connection)
'.........Соответствующий код для установления соединения с базой данных здесь опущен
adoconnection.execute exec dt_GetNews +request(тип новости)
adoconnection.close
%>
Если значение request(newstype) равно 1, результатом операции будет возврат всех записей с полем newstype в таблице новостей, равным 1. Однако, если значение request(newstype) равно 1, удалить таблицу news; , возвращается результат: таблица новостей удалена.
Из этого примера видно, что даже использование хранимых процедур все равно будет атаковано. Кроме того, выберите * из новостей, где newstype=@newstype не является сращиванием, поэтому не существует неизбежной связи между сращиванием строк SQL-запроса и атаками с использованием SQL-инъекций. хранимые процедуры могут оказаться неспособными защитить от атак путем внедрения.
Так как же написать его, не подвергнувшись атаке SQL-инъекцией? Ниже я представлю последний метод. Грубо говоря, он очень простой и примитивный: проверка типа данных и замена одинарных кавычек. Будь то Oracle, Sql Server, mySql, Access или другие реляционные базы данных, типы полей можно грубо разделить на две категории: числовые типы (например, int, float и т. д.) и символьные типы (например, char, varchar и т. д.). ). Соответствующие операторы SQL немного отличаются в зависимости от типа поля, например:
Поле типа новостей в поле «Выбрать * из новостей», где newstype=1, должно быть числовым.
select * from news где newstype='social news' поле типа новостей должно быть символьным.
Для числовых полей нам необходимо проверить тип данных параметра. Например, когда мы создаем оператор запроса, используя select * from news, где newstype=+v_newstype, мы должны проверить тип данных переменной v_newstype. не менее Это должно быть число, которое может быть целым числом или числом с плавающей запятой. Если такая проверка выполнена, выберите * from news, где newstype=+v_newstype никогда не создаст что-то похожее на select * from news, где newstype=1. ;уронить Заявления типа настольных новостей. Причина, по которой ASP более уязвим для атак, чем ASP.Net, JSP и т. д., заключается в том, что переменные в ASP не нужно объявлять, а тип переменной неясен.
Для символьных полей нам необходимо обработать одинарные кавычки ('). Метод обработки заключается в замене одной одинарной кавычки двумя одинарными кавычками (''). Например, мы используем select * from news, где. Когда newstype='+v_newstype+' используется для создания оператора запроса, одинарная кавычка в v_newstype должна быть заменена двумя одинарными кавычками, поскольку в SQL часть, заключенная в две одинарные кавычки, представляет строку, а две последовательные одинарные кавычки quote представляет собой одиночный символ кавычки. После такой обработки мы рассмотрим метод построения select * from news, где newstype='+v_newstype+', когда значение v_newstype равно:
Социальные новости';выпадающие новости таблицы--
После замены одной одинарной кавычки на две одинарные кавычки значение v_newstype становится следующим:
Социальные новости''; новости из таблицы сброса--
Сконструированный оператор SQL становится:
выберите * из новостей, где newstype='social news'';drop table news—'
Результатом запроса является возврат записей, значение поля newstype в таблице новостей которых равно социальным news';drop table news--, без удаления таблицы новостей, как раньше.
Кроме того, необходимо обработать не только оператор Select, включая Insert, Update, Delete, Exec и т. д., вы можете взглянуть на следующие методы внедрения:
В структуру вставляем в news(title) значения('+v_title+'),
When v_title=123';отбросить новости таблицы--';
При обновлении новостей установите /> When v_title=123'-- или v_id=1;удалить таблицу новостей--, так что это не только проблема с оператором Select, но и другие операторы могут иметь проблемы, не сосредотачивайтесь только на Select
Короче говоря, после проверки типа данных и обработки символов одинарных кавычек, даже если он обладает всеми способностями, он не сможет вылететь из ладони моего Татхагаты.