Статьи

Программное обеспечение CenterEdge: Couchbase и N1QL Security

Примечание: это гостевой пост  Бранта Бернетта  из  CenterEdge Software , компании, которая разрабатывает POS и специальное программное обеспечение для индустрии развлечений, отдыха и развлечений.

обзор

N1QL — это невероятно мощный новый инструмент, который поможет донести базы данных NoSQL до более широкого круга разработчиков с гораздо меньшей степенью обучения. Это поможет разработчикам создавать современные, производительные и надежные приложения быстрее и проще, чем когда-либо прежде. Но с любой новой технологией площадь атаки хакеров по своей сути увеличивается.

Внедрение SQL — это хорошо известный недостаток безопасности, обычно встречающийся в приложениях на основе SQL, и он был очень хорошо задокументирован за эти годы. Итак, как N1QL сравнивается с SQL с точки зрения безопасности? Является ли N1QL уязвимым и для инъекционных атак? Если так, как разработчики могут избежать этих ловушек?

Обзор SQL-инъекций

Внедрение SQL — это форма внедрения кода, при которой конечный пользователь может добавлять вредоносный код в запросы SQL, выполняемые вашим приложением. Простой пример этого запроса:

var query = "SELECT * FROM users WHERE name ='" + userName + "'";

Если разработчик не предпримет шаги для защиты своего приложения, пользователь может включить вредоносный текст в поле userName. Например:

ВЫБЕРИТЕ * ОТ ПОЛЬЗОВАТЕЛЕЙ, ГДЕ name = » OR ‘1’ = ‘1’

Этот запрос является результатом ввода пользователем «‘ИЛИ’ 1 ‘=’ 1». Теперь запрос вернет всех пользователей в системе злоумышленнику.

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

var query = "SELECT * FROM users WHERE name = '" + userName + "' AND group = 5";

Могут быть введены с:

SELECT * FROM users WHERE name = '' OR 1=1 --' AND group = 5

Так как SQL будет игнорировать весь текст после «-», ограничение, что группа должна быть 5, теперь удалено из запроса. Еще раз, все пользователи в системе возвращаются злоумышленнику.

Пользователь может также объединить комментарии с пакетными командами для изменения данных в вашей базе данных:

SELECT * FROM users WHERE name = 'blah'; DROP TABLE auditlog /*’AND group = 5

Как это влияет на N1QL?

После некоторых экспериментов N1QL фактически более устойчив к атакам с использованием инъекций, чем традиционный SQL. Тем не менее, злоумышленник все еще может выполнить атаку. Без защиты эти атаки могут привести к разрешению доступа к защищенным данным или к отказу в обслуживании, поскольку измененные запросы используют слишком большую вычислительную мощность в кластере Couchbase.

В настоящее время N1QL не поддерживает пакетирование нескольких команд. Поэтому нет эквивалента пакетным атакам, которые допускают злонамеренное изменение данных в SQL. Тем не менее, пакетная обработка, безусловно, может быть добавлена ​​в качестве новой функции в будущей версии N1QL. Поэтому, если разработчики не защищают ввод данных пользователем в своих запросах, изменение данных может стать проблемой в будущем.

Где пункт оговорки

Как и в случае SQL-инъекции, N1QL-инъекция позволяет изменять предложение WHERE. Например:

var query = "SELECT * FROM users WHERE name = '" + userName + "'";

Может стать:

SELECT * FROM users WHERE name = '' OR '1'='1'

Из-за правил приоритета операторов для операторов AND и OR эта атака может даже работать, если есть дополнительные условия:

var query = "SELECT * FROM users WHERE name LIKE '%" userName + "%' AND group = 5

По-прежнему возвращает всех пользователей, когда это становится:

SELECT * FROM users WHERE name LIKE '%' OR ''='%' AND group = 5

N1QL Комментарии

Система комментариев N1QL использует блоки комментариев в стиле C (/ * comment * /) вместо «-» для закомментирования оставшейся части строки. Это защищает N1QL от некоторых более сложных инъекционных атак. Поскольку N1QL требует заключительный комментарий * /, злоумышленники не могут закомментировать части вашего запроса, не вызвав синтаксической ошибки.

Однако обратите внимание, что это зависит от того, не проявит ли разработчик комментарии в своем запросе. Если в тексте запроса есть комментарий, у пользователя теперь есть закрывающий блок комментариев, который можно использовать в своих интересах:

var query = "SELECT * FROM users WHERE name = '" + userName + "' AND group = 5 /* only return group 5 */";

Может быть введен с помощью «ИЛИ 1 = 1 / *»:

SELECT * FROM users WHERE name = '' OR 1=1 /*' AND group = 5 /* only return group 5 */

Как и в примере SQL, ограничение группы теперь удалено из запроса.

Инъекция идентификатора N1QL

Модель безсхемного документа Couchbase создает новую интересную область атаки. При работе с SQL очень редко включать пользовательский ввод где-либо, кроме предложения WHERE или ORDER BY вашего запроса. Это потому, что имена таблиц и столбцов хорошо известны и не меняются.

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

var query = "SELECT " + field + " FROM users WHERE type = 'user'";

После инъекции становится:

SELECT name, (SELECT * FROM users as users2 USE KEYS users.userPasswordDocumentIds) as passwordDoc FROM users WHERE type = 'user'

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

Как защитить ваше приложение

К счастью, защитить приложение от атак внедрения N1QL так же легко, как и от атак внедрения SQL. Вот несколько рекомендаций, которые облегчают безопасность. Примеры в C #, но концепции применимы так же, как и к любому другому языку.

  1. Рекомендация.  Вместо того чтобы вставлять пользовательский ввод непосредственно в запрос, в качестве защиты используйте именованные или позиционные параметры. Таким образом, пользовательский ввод никогда не добавляется непосредственно к вашему запросу, обеспечивая 100% защиту от всех атак с использованием инъекций.
    var query = "SELECT * FROM users WHERE userName = '" + userName + "'";

    Должно быть:

    var query = new QueryRequest("SELECT * FROM users WHERE userName = $userName");
    query.AddNamedParameter(“$userName”, userName);
  2. Если вы вставляете пользовательские строки ввода в свой запрос, всегда избегайте кавычек. Замените любой экземпляр одинарной кавычки (‘) двумя одинарными кавычками (‘ ‘).
    var query = "SELECT * FROM users WHERE userName = '" + userName + "'";

    Должно быть:

    var query = "SELECT * FROM users WHERE userName = '" + userName.Replace("'", "''") + "'";
  3. При вставке пользовательских идентификаторов ввода в ваш запрос всегда экранируйте идентификатор с помощью галочек (`). Затем замените любой экземпляр тика на входе двумя тиками («). Обратите внимание, что для идентификаторов нет эквивалента именованного параметра, поэтому экранирование — это лучшее решение.
    var query = "SELECT " + field + " FROM users WHERE group = 5";

    Должно быть:

    var query = "SELECT `" + field.Replace("`", "``") + "` FROM users WHERE group = 5";
  4. Если вы реализуете другие правила, вы также защищены от атак на основе комментариев. Однако вторичная политика в отношении комментариев в запросах, содержащих пользовательский ввод, может обеспечить дополнительную защиту в случае, если разработчик забудет другие правила. Вместо этого просто поместите любые комментарии в код приложения вместо самого запроса.
    var query = "SELECT * FROM users WHERE userName = '" + userName + "' AND group = 5 /* only return group 5 */";

    Должно быть:

    var query = "SELECT * FROM users WHERE userName = '" + userName.Replace("'", "''”) + "' AND group = 5"; // only return group 5

Чтобы увидеть примеры этих атак и способы их защиты в C #, пожалуйста, смотрите репозиторий GitHub:  https://github.com/brantburnett/N1QlInjection . Обратите внимание, что для запуска тестов вам потребуется установить Couchbase локально, а также образец пива.

Вывод

Хотя N1QL уязвим для атак с использованием инъекций, эта уязвимость ничем не хуже известных уязвимостей в SQL. Кроме того, разработчикам очень легко защитить себя от инъекционных атак. Поэтому N1QL предоставляет отличную платформу для разработки защищенных приложений с использованием баз данных Couchbase NoSQL.