Система автоматизированной проверки правильности составления SQL-запросов: защита от уязвимостей

УДК 004.655.3

СИСТЕМА АВТОМАТИЗИРОВАННОЙ ПРОВЕРКИ ПРАВИЛЬНОСТИ СОСТАВЛЕНИЯ SQL-ЗАПРОСОВ: ЗАЩИТА ОТ УЯЗВИМОСТЕЙ

З. В. Семенова, С. А. Любич, А. Г. Кузнецов, П. А. Мальцев

Сибирский автомобильно-дорожный университет, г. Омск, Россия

DOI: 10.25206/2310-9793-2017-5-4-90-95

Аннотация - В статье представлено описание наиболее часто встречающихся уязвимостей систем проверки правильности составления SQL-запросов. Обосновывается, что целесообразно в качестве основного инструмента закрытия таких уязвимостей, как «Обход решения» использовать теневую базу данных. Для закрытия такой уязвимости, как «Нечувствительность к порядку полей в команде SELECT» - механизм курсоров в связке с созданием и сравниванием словарей вида «Ключ-Значение» .

Ключевые слова: база данных, теневая база данных, схема БД, SQL-запрос, система тестирования.

I. Введение

О крайне высокой потребности в разработке системы автоматизированной проверки правильности составления SQL-запросов мы уже указывали в одной из наших публикаций [1]. Основное назначение такой системы - возможность отработки навыков владения языком структурированных запросов (работа такой системы в режиме тренажера), а также оценка того, как тестируемый справляется с заданиями. Несмотря на то, что подобных систем и сервисов достаточно много, не любая из них может быть использована в условиях, когда проверяющий (преподаватель или представитель компании, которая нуждается в специалисте, отлично владеющем SQL) имеет возможность задать свою «планку» для тестирования. Более того, многие из таких систем имеют уязвимости, которых нельзя допускать при построении новой аналогичной системы (нового сервиса).

II. Характеристика основных уязвимостей систем

для проверки правильности составления SQL-запросов Большинство подобных ресурсов разработаны энтузиастами и находятся в свободном доступе. В качестве примера можно привести систему SQL-тренажер, одним из важных достоинств которой является то, что она, как отмечают разработчики, имеет возможность интеграции с модульной объектно-ориентированной динамической учебной средой Moodle, с целью комплексного контроля успеваемости студентов по другим разделам изучаемой дисциплины [2]. Кроме того, преподаватель имеет возможность самостоятельно формировать тестовые задания, а значит, ориентироваться на логику собственного изложения материала и учитывать особенности учебной группы. Вместе с тем, анализ архитектуры системы позволяет констатировать, что с точки зрения проверки правильности написания SQL-запроса данная система аналогична многим подобным. Заметим, что аналогичные системы нацелены на помощь в изучении языка SQL. Так, например, автор ресурса PostgreSQL Exercises (https://pgexercises.com/) отмечает, что идея создания сайта пришла к нему тогда, когда он понял, что на самом деле мало тренировочных материалов для отработки навыков написания запросов к базе данных, созданных в СУБД PostgreSQL [3]. Представляется, что поскольку ресурс ориентирован на тех, кто в дополнение к изучению PostgreSQL по учебникам и по документации, рассматривает этот сайт, как помощник в самостоятельном освоении языка SQL и, следовательно, не ориентированы на деструктивные действия, то и нет особой потребности в закрытии некоторых уязвимостей. Одной из таких уязвимостей является возможность ввести некорректный ответ, который будет воспринят системой как верный.

Приведем пример, иллюстрирующий сказанное. Пользователю предъявляется задание, требующее от него ответить на следующий вопрос: «Как составить список тех, с кого взимаются членские взносы?». Структура базы данных представлена на рис. 1. Фактически необходимо вывести все поля из таблицы Льготы (facilities), где значение поля membercost отличается от нуля. Самый первый и верный вариант ответа будет следующим: select * from cd.facilities where membercost>0;

Система совершенно верно оценила такой вариант ответа. Также в качестве корректных вариантов система восприняла и другие ответы:

select * from cd.facilities where membercost<>0; select * from cd.facilities where not(membercost=0);

Заметим, что, действительно, все представленные выше варианты являются корректными с точки зрения формулировки задания (вопроса). Однако при некорректном логическом выражении (т.е. по факту некорректном запросе), когда лишь выдача (результирующая таблица - представление) будет совпадать с результатом, полученным при корректном запросе, система также оценит запрос как верный. Так, в частности, система оценила как корректный следующий запрос: select * from cd.facilities where guestcost=25 or guestcost=80 or guestcost=17.5;

Рис. 1. Схема базы данных ресурса PostgreSQL Exercises

Это позволяет сделать вывод, что система не производит синтаксический анализ введенной строки (введенного запроса). Она лишь сверяет результат хранимого на сервере запроса (в соответствии с тем вариантом, который автор теста заложил в систему) с результатом, который в итоге будет получен в ответ на запрос, составленный пользователем. Составить не отвечающий заданию запрос (фактически неправильный), некорректность которого система не распознала, стало возможным в связи с тем, что сама БД является небольшой (всего 8 записей). С аналогичной ситуацией можно столкнуться и на обучающем ресурсе Стэнфордского университета. В ходе изучения системы удалось выполнить неправильный запрос так, чтобы система сочла его корректным.

В предъявленном системой задании требовалось выбрать название фильма из таблицы Movie, директор которого - Спилберг. Содержание данных предложенной таблицы (Movie) представлено на рис. 2.

Movie

in ID title year director

101 Gone with the Wind 1939 Victor Tleming

102 Star Wars 1977 George Lucas

103 The Sound of Music 1965 Robert Wise

104 E.T. 1982 Steven Spielberg

105 Titanic 1997 James Cameron

106 Snow White 1937 <null>

107 Avatar 2009 James Cameron

10S Raiders of the Lost Ark 1981 Steven Spielberg

Рис. 2. Содержание данных предложенной таблицы Movie

Очевидно, что корректным в данном случае будет следующий запрос: select title from Movies where director='Steven Spielberg';

Однако и в этом случае можно составить некорректный запрос, который система оценит, как верный, а именно:

select title from Movies where title = 'E.T.' or title ='Raiders of the Lost Ark';

Заметим, что немалое количество аналогичных систем не способны распознавать SQL-запросы, которые не удовлетворяют условию задачи, но результат их выполнения совпадает с тем, что ожидает приложение. Это возникает не только в том случае, когда в предложении where команды select происходит подмена полей, но и в других ситуациях. Так, например, когда исходная таблица (таблицы) заполнены небольшим количеством записей, а нужный нам результат (в соответствии с заданной задачей) находится на самых верхних строчках, можно использовать предложение TOP команды select для вывода лишь первых N записей. Еще один вариант - варьировать использованием агрегированных функций. Таким образом, существует немало способов «обхода системы».

Если в приведенных примерах некорректно составленный пользователем запрос воспринимался системой, как верный, то следует констатировать, что для абсолютно всех проанализированных систем проверки правильности написания SQL-запросов в случае, если пользователь нарушил порядок следования полей в запросе, запрос будет интерпретирован, как неверный, о чем мы уже писали [1]. Мы убеждены, что лишь в отдельных случаях (отдельных запросах) порядок следования полей имеет значение, а система должна обеспечить при необходимости такую характеристику, как «Нечувствительность к порядку полей в команде SELECT» [1].

III. Способы закрытия уязвимостей

Основная причина, по которой тестируемый имеет возможность осуществить «обход системы» - это возможность проанализировать содержимое базы данных. Не предъявлять ее вовсе тоже не является корректным. Логичным решением здесь является создание так называемой теневой базы данных, структура которой совпадает со структурой основной БД и содержание которой не видит тестируемый. Но, даже если бы он видел ее, подобрать такой вариант запроса (не соответствующий заданию), который одновременно выдавал корректный результат на основной и теневой базе данных практически невозможно. Подобное решение используется разработчиками. Например, лишены подобных проблем такие ресурсы, как CodeWars (Codewars.com), Sql-ex (www.sql-ex.ru), TestDome (www.testdome.com). Таким образом, закрыть такую уязвимость необходимо уже на стадии определения архитектуры системы.

Разработанная нами система проверки правильности составления SQL-запросов имеет архитектуру, предусматривающую наличие теневой базы данных (рис. 3).

Рис. 3. Архитектура системы проверки правильности составления SQL-запросов

Заметим, что подобное архитектурное решение, основанное на стеке технологий Python+Django+JS+HTML+CSS, в целом повышает безопасность всей системы. Как известно, дополняющий Python фреймворк Django, поддерживающий концепцию MVT - Model-View-Template (Модель-Представление-Шаблон), даёт возможность разделить модель приложения, интерфейс пользователя и взаимодействие с поль-

зователем. Кроме того, Django имеет стандартные возможности по обеспечению безопасности приложения, а именно [4]:

- защита от межсайтового скриптинга (XSS);

- защита от подделки межсайтового запроса (CSRF);

- защита от SQL инъекций;

- защита от кликдженкинга;

- защита от перехвата данных при отсутствии HTTPS;

- проверка заголовка хоста;

- безопасность сессий.

Ещё одной уязвимостью можно считать установку соединения с СУБД во время прохождения теста. Если администратор автоматизированной системы будет невнимателен и укажет в строке соединения с СУБД пользователя с правами администратора или с правами на возможность модификации, удаления данных и таблиц или с возможностью просмотра всех баз данных, то это может скомпрометировать результаты теста у одного тестируемого, а в худшем случае - полностью сорвёт тестирование. Может случиться и так, что понадобится восстановление базы данных.

Уязвимости, связанные с сохранением прав на возможность удалить или модифицировать данные, являются очевидными и также очевиден способ закрытия такой уязвимости. Реализуется это за счет предоставления пользователю прав только на выборку из базы данных. Заметим, что, фактически, данный способ является известным и, например, используется в таком ресурсе, как CodeWars. При тестировании по языку SQL разрешено начинать запрос только с ключевого слова «SELECT».

Если проблемы указанные выше разработчики, как правило, отслеживают, то возможность просмотра всех существующих БД могут оставить без внимания. Это открывает злоумышленнику доступ к теневой базе данных и к тому, что в ней хранится. В таком случае метод сравнения результатов запроса становится снова уязвим к простому подбору данных, которые необходимо получить. Чтобы закрыть эту уязвимость пользователю, через которого установлено соединение, необходимо ограничить обзор до одной базы данных.

Из всего выше сказанного следует, что администратору необходимо:

- для соединения с базой данных создавать пользователя, который имеет право на просмотр только одной базы данных и способен только на выборку данных.

- для теневой и открытой базы данных пользователи должны также отличаться.

Что же касается такой уязвимости, как «Нечувствительность к порядку полей в команде SELECT», то ее можно также устранить, создав на языке Python дополнительный код.

Здесь важно предусмотреть в итоге использование того же механизма проверки, что и в случае чувствительности к порядку следования полей. В данном случае придется использовать механизм курсоров. Как известно, курсор (Cursor) используются для выполнения запросов к базе данных, фактически является инструментом SQL-драйвера, тип которого определяется типом СУБД.

Важно учитывать, что после выполнения запроса его результат хранится в курсоре в определенном виде: сначала заголовок, потом результат в соответствующем количестве экземпляров (строк). Например, это может выглядеть так:

[('id','name','age'),('1','Artem','22'),('2','Pavel','22')J

Тогда обеспечить «Нечувствительность к порядку полей в команде SELECT» благодаря последовательности следующих действий:

- из курсора извлечь результаты запроса (без названия полей) и поместить их в список для дальнейшей работы;

- из курсора извлечь названия полей и поместить их в другой список;

- создать словарь вида "Ключ-Значение", где Ключ - название поля, Значение - список, в котором находятся все значения выбранного поля;

- заполнить словарь;

- сравнить словари (примечание: в языке Python словари можно сравнивать, используя "==").

Фрагмент программной реализации описанного алгоритма представлен на рис. 4.

try:

1 = []

11 = []

з1 = [] all « [3

curs = Connect.cursor О

(полученный результат (без названия колонок} сохраняем е список для последующей обработки

I = [row for row in curs]

column name = [row[0] for row in curs.description]

#Зыполняется эталонный запрос к открытой БД. Результат сохраняется в ппеременной сигз cursl = Connect.сигзог{)

cursl „ execute (str (task:, get (id=int {temp) ) .WTask) }

#полученный результат (без названия колонок) сохраняем в список для последующей обработки

II = [row for row in cursl]

calunm_nan:e_w = [row[0] for row in cursl. description] Shadowcurs = ConnectShadow.cursorO

выполняется запрос пользователя к теневой 5Д. Результат сохраняется в ппеременной curs Shadowcurs.execute

(полученный результат (без названия колонок) сохраняем ь список для последующей обработки si = [row for row in Shadowcurs]

coluim_name_shadow = [row[0] for row in Shadowcurs.description] Shadowcur si = Conneс 15hadow.cur s о r{)

выполняется эталонный запрос к тенеЕсй 2Д. Результат сохраняется в ппеременной сигз Shadowcur3l.execute

#полученный результат (без названия колонок) сохраняем е список для последующей обработки sll = [row for row in Shadowcursl]

column_nam.e_w_3hadow = [row[C] for row in Shadowcur3l.description]

#Создание словарей...

dic_check_student_l±ght_table = { t

die check student shadow table = {}

dic_check_teacher_light_tahle = {J

dic_check_teacher_shadow_table = J)

#И инициализация

for 3 in range (len(coluim_nair.e) ) :

dic_check_student_light_tatle icoluinn_nam.e [ j ] ] - [row[j] for row in 1]

for j in range (1 en{column_naiEe_shadow) ) :

dic_ciieck_3tudent_3hadow_table [coluian_name_3hadowl i ] ] = [rowjj] for row ill 31]

for j in range (len{column_nair.e_w> ) :

die check teacher light table[column name w[j]] = [row[j] for row in 11]

for j in range (1 en fcolurcn_nair.e_w_shadow) ) :

die check teacher shadow table[column name w shadowjj]] = [row[j] for row in sll]

Рис. 4. Фрагмент кода, реализующего «Нечувствительность к порядку полей в команде SELECT»

IV. Выводы и заключение Для снижения количества уязвимостей в системе проверки правильности составления SQL-запросов необходимо тщательно продумывать архитектурное решение. Существенную роль здесь играет не только наличие теневой базы данных, но и планирование доступа к ней. Важно предусмотреть возможность для тестируемого доступ только к одной базе данных. Важно четко разграничить пользователей с точки зрения их доступа к теневой базе данных. Кроме того для того, чтобы обеспечить «Нечувствительность к порядку следования полей в команде SELECT» необходимо использовать механизм курсоров, а также создание и сравнивание словарей вида «Ключ-Значение».

Список литературы

1. Семенова З. В., Любич С. А., Кузнецов А. Г., Мальцев П. А. Сравнительная характеристика средств автоматизированной проверки правильности составления SQL-запросов // Вестник СибАДИ. 2017. № 3 (55). С. 152160.

2. Семенов Г., Саргсян С., Науменко С. SQL-тренажер по дисциплине «Управление данными» // Информационные ресурсы России. 2012. № 2. URL: http://www.aselibrary.ru/press_center/journal/irr/irr3648/irr36483677/irr364836773683/irr3648367736833693/.

3. PostgreSQL Exercises. URL: http://pgexercises.com/.

4. Безопасность в Django: документация Django 1.4. URL: https://djbook.ru/rel1.4/topics/security.html. УДК УДК 004.8

РАСПОЗНАВАНИЕ ПОЛЬЗОВАТЕЛЕЙ КОМПЬЮТЕРНЫХ СИСТЕМ ПО КЛАВИАТУРНОМУ ПОЧЕРКУ С УЧЕТОМ ПАРАМЕТРОВ ВИБРАЦИИ И ДАВЛЕНИЯ НА КЛАВИШИ

А. Е. Сулавко1, А. А. Федотов2, А. В. Еременко2

'Омский государственный технический университет, г. Омск, Россия 2Омский государственный университет путей сообщения, г. Омск, Россия

DOI: 10.25206/2310-9793-2017-5-4-95-105

Аннотация - Рассматривается проблема защиты данных от неавторизованного доступа посредством проведения аутентификации субъектов по клавиатурному почерку. Предложено использовать параметры давления на клавиши и вибрации клавиатуры совместно с временными характеристиками нажатия клавиш для распознавания печатающего субъекта. Разработана клавиатура с использованием специальных датчиков, позволяющих регистрировать дополнительные параметры. Проведена оценка информативности новых признаков, а также вероятностей ошибок распознавания субъектов на основе персеп-тронов, формулы Байеса и сетей квадратичных форм. Наилучший результат: количество ошибок идентификации 20 человек составило 0,6 %.

Ключевые слова: Давление на клавиши, вибрация клавиатуры, широкие искусственные нейронные сети, корреляция между биометрическими признаками, плотность вероятности.

I. Введение

В настоящее время активно идут процессы информатизации общества. Появляется все больше веб-сервисов. Многие государства стремятся создать электронное правительство для оказания услуг гражданам. Доверие к таким веб-сервисам со стороны пользователей должно быть наивысшим. Однако большинство утечек конфиденциальной информации и кибератак приходится именно на веб-сервисы. Их количество в мире каждый год возрастает [1]. Имеющиеся оценки мировых финансовых потерь от этих инцидентов впечатляют: по имеющимся данным они составляют до 375-575 млрд. долларов США в год [2]. Чтобы снизить потери, в организациях различного уровня внедряются биометрические системы защиты. По данным на октябрь 2016 года 57 % предприятий используют биометрическую аутентификацию [3].

Статические биометрические образы (отпечаток пальца, сетчатка или радужка) не являются секретными, поэтому их можно скопировать, изготовив физический или цифровой муляж (для удаленной аутентификации). Тайные биометрические образы содержат в себе секрет (пароль) и поэтому потенциально могут обеспечить более высокий уровень защиты. К их числу относится индивидуальный клавиатурный почерк субъекта, проявляющийся при наборе парольной фразы. Недостаток метода аутентификации по клавиатурному почерку состоит в сравнительно низкой надежности принимаемых решений - вероятности ошибок ложного отказа в доступе (FRR) и ложного доступа (FAR) слишком значительны для использования метода на практике [4]. Данная работа посвящена повышению надежности распознавания субъектов по клавиатурному почерку посредством использования дополнительных признаков, характеризующих динамику набора текста на клавиатуре: параметры давления (силы нажатия) на клавиши и вибрации клавиатуры.

II. Разработка модифицированной клавиатуры для сбора биометрических данных

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