Компания
95,29
рейтинг
16 мая 2012 в 13:01

Разработка → Азбука NoSQL-инъекций

Бывают SQL-инъекции! А возможны ли NoSQL-инъекции? Да! Redis, MongoDB, memcached — все эти программные продукты относятся к классу нереляционных СУБД, противоположному популярным MySQL, Oracle Database и MSSQL. Так как интерес к перечисленным базам данных в последнее время значительно возрос, хакеры всех мастей просто не могли пройти мимо них.




Что такое NoSQL


Думаю, ты знаком с реляционной моделью СУБД, согласно которой база данных состоит из сущностей (таблиц), связанных между собой. Доступ к данным осуществляется с помощью SQL — структурированного языка запросов. За примерами реляционных СУБД далеко ходить не надо: MySQL, Oracle, Microsoft SQL Server. Все остальные СУБД, архитектура которым отличается от классической реляционной модели, смело можно отнести к классу NoSQL-решений:
  • различные варианты хеш-таблиц (Redis, BigTable, memcached);
  • документо-ориентированные базы данных (MongoDB, CouchDB);
  • базы данных, основанные на графах (Neo4j, Sones GraphDB);
  • объектно-ориентированные базы данных (db4o, Cache, Jade);
  • XML-ориентированные базы данных (eXist, BaseX).

Основное отличие NoSQL-СУБД от их SQL-ориентированных конкурентов заключается в отсутствии единого, унифицированного языка запросов. Например, MongoDB использует в качестве языка запросов BSON, eXist применяет XQuery, а Sonic GraphDB требует от разработчика знания GraphQL, языка запросов к данным, имеющим вид графов. Популярность NoSQL-СУБД растет с каждым днем, что не может не сказываться на нас с тобой. Совсем скоро, буквально завтра, тебе придется искать не SQL-инъекции, а NoSQL-инъекции в очередном проекте. Не будем терять времени и поговорим о потенциальных уязвимостях.

Так ли безопасны NoSQL-СУБД?


Довольно часто я слышу утверждение, что нереляционные СУБД безопасны, так как они не используют SQL и злоумышленник не может провести на них атаки типа SQL-injection. В какой-то степени это верно: нет SQL — нет SQL-инъекций. Но, если в систему невозможно внедрить SQL-код, это еще не значит, что она безопасна. NoSQL закрывает одну потенциальную уязвимость, при этом открывая с десяток других, которые позволяют совершать разнообразные вредоносные действия:
  • манипулировать с REST-интерфейсом и подделывать межсайтовые запросы (CSRF);
  • использовать регулярные выражения в параметрах запроса;
  • выполнять скрипты на сервере, если на нем установлена NoSQL-СУБД (например, MongoDB позволяет запускать JavaScript-код);
  • получать доступ к данным через специальный интерфейс, поддерживаемый СУБД (SQL в реляционных базах данных, BSON в MongoDB и т. д.), и, если используется язык запросов, «исправлять» эти запросы.

Рассмотрим типовую архитектуру приложения с доступом к хранилищу данных NoSQL. Обычно она состоит из трех уровней:
  • приложение;
  • API базы данных NoSQL;
  • NoSQL-СУБД.

Злоумышленник может атаковать каждый из этих уровней. Начнем с самого нижнего уровня, то есть непосредственно с СУБД.Как и любое приложение, СУБД может быть подвержена атакам переполнения буфера или иметь уязвимую схему аутентификации. Атаковать этот уровень довольно сложно, потому что сообщество, сформировавшееся вокруг продукта, и сама компания-разработчик стараются исправлять ошибки по мере их обнаружения. Но у тебя есть очень большое преимущество: большинство программных продуктов поставляются с исходным кодом, а значит, ты вполне сможешь его проанализировать и, возможно, найти что-нибудь стоящее. Если тебе повезет, то в твоих руках окажется ключ практически к любой базе данных! Следующий уровень — клиентское API. Большинство NoSQL-СУБД имеют целый зоопарк различных библиотек для доступа к данным. Стоит отметить, что большинство библиотек представляют собой проекты с открытым исходным кодом, но часть из них уже не поддерживается. Вероятность обнаружить уязвимость в клиентской библиотеке значительно выше, чем непосредственно в самой СУБД. И даже если тебе не посчастливится найти ту единственную уязвимость, которая откроет доступ ко всем приложениям, построенным на основе этого API, ты будешь представлять, как именно происходит диалог между клиентским кодом и сервером баз данных, какой используется протокол и можно ли перехватить сессию.
Ну и наконец, верхний уровень — приложение, которое ты собираешься взломать. Здесь тебе прежде всего нужно найти те места, где программист забыл проверить входные данные, и попытаться их проэксплуатировать. В данном случае нужно использовать тот же подход, что и при поиске SQL-инъекций, то есть анализировать код и сообщения об ошибках, только на этот раз придется разбираться с JSON, JavaScript или чем-то подобным.
Итак, настало время для взлома! Сегодня нашей целью будет MongoDB — одна из самых распространенных NoSQL-СУБД.

NoSQL-инъекции в MongoDB


Мы будем взламывать небольшое web-приложение. Вот его исходный код (процесс установки подробно описан в файле README.RU.txt). Если установка пройдет успешно, то приложение должно быть доступно по адресу http://127.0.0.1:31337. Основные атаки, о которых сегодня пойдет речь:
  • инъекции в регулярных выражениях;
  • JSON-инъекции;
  • манипуляции с REST-интерфейсом;
  • JavaScript-инъекции.

Начнем со взлома при помощи ошибок в использовании регулярных выражений.


Web-интерфейс MongoDB

Инъекции в регулярных выражениях


MongoDB, как и многие другие NoSQL-СУБД, позволяет осуществлять поиск с помощью регулярных выражений. Это очень мощное, но в то же время опасное средство, которое может нанести существенный вред при неправильном использовании.
Для поиска с помощью регулярных выражений в MongoDB используют оператор $regex. Например, запрос «верни мне всех пользователей, логин которых начинается с «ro»», будет выглядеть следующим образом:

db.users.find({ login: { $regex: "^ro" } })

Кстати, если ты не знаком с языком запросов MongoDB, то рекомендую начать его изучение с руководства разработчика. Но вернемся к нашему приложению. Открой тестовый web-сайт и выбери пункт «Инъекции в регулярных выражениях» в меню MongoDB.


Страница аутентификация пользователя в тестовом приложении

Посмотрим, как устроена эта страница. Открой файл mongodb.js в папке Lib. В нем реализован класс MongoDbController, который отвечает за функционирование всех страниц в приложении. Сейчас нас интересует метод regexp:

var regexpPwd = new RegExp("^" + password, "i");
var loginParam = { login: login, password: regexpPwd };

Как видишь, аутентификация пользователя происходит посредством запроса, который указывает регулярное выражение в качестве пароля. При этом переменная password никак не фильтруется, что открывает нам полную свободу действий. Здесь ты можешь указать имя пользователя root и регулярное выражение вместо пароля, например [\s\S]*. В результате MongoDB выполнит следующий запрос: «db.users.findOne({login: 'root', password: /^[\s\S]*/i})», и ты успешно войдешь на уязвимый сайт под логином root (этот прием напоминает классическую SQL-инъекцию «1' or 1=1 --»). Защититься от подобной атаки довольно просто. Во-первых, всегда проверяй входные данные, откуда бы они ни поступили — напрямую от пользователя, или из внешнего файла, или из базы данных. Перед использованием данных в программе их следует проверять. Во-вторых, используй регулярные выражения только в тех случаях, когда это действительно необходимо. Например, приведенный выше запрос можно переписать вот таким образом:

db.users.findOne({ login: 'root', password: 'p@ssw0rd' })

Как видишь, он безопаснее и при этом выполняется быстрее.

JSON-инъекции


Да, MongoDB не поддерживает SQL, но СУБД не может обойтись без языка запросов. Разработчики MongoDB решили использовать вместо SQL популярнейший текстовый формат обмена данными JSON (BSON). Таким образом, можно попробовать осуществить разного рода атаки-инъекции (конечно, если входные данные не фильтруются). Такие атаки обычно называют JSON-инъекциями.
Итак, снова открывай наше приложение и переходи на страницу «JSON-инъекции». Как и в предыдущем примере, ты увидишь поле для ввода имени пользователя и пароля. Давай рассмотрим код, отвечающий за процесс аутентификации на этой странице. Он содержится в методе json-injection класса MongoDbController:

var loginParam = eval("({ login: '" + login + "',
                       password: '" + password + "' })");

Вышеприведенный код преобразует текстовое представление объекта JavaScript (запроса к MongoDB) в объект. После передачи этого объекта на сервер баз данных происходит аутентификация пользователя. В этом куске кода есть одно очень слабое место — входные данные никак не контролируются, поэтому ты можешь сформировать практически любой запрос к базе! Например, укажи имя пользователя «root'})//» (пароль вводить необязательно) и нажми на кнопку «Войти». Поздравляю, ты снова вошел в систему! Как так получилось? Все очень просто. Ты указал имя пользователя «root'})//», и в функции eval произошел следующий фокус:

//Переданное значение
({ login: 'root'})//', password: '' })

//Получившийся запрос
db.users.findOne({ login: 'root' })

На самом деле этот скрипт даже еще опаснее, так как с его помощью ты можешь выполнить любой код JavaScript на web-сервере. Например, имя пользователя "' + process.execPath})//" сформирует запрос вида

db.users.findOne({ login: 'C:\\node.exe' })

Уязвимости такого типа называются Server Side JavaScript Injections или просто SSJI.
Как же защититься от подобных атак?
  1. Проверяй все данные из внешних источников. Например, логин должен соответствовать регулярному выражения "^[a-zA-Z]+$".
  2. Никогда не используй функцию eval для работы с JSON. В Node.js доступна функция JSON.parse, которая парсит входную строку и создает объект на ее основе.



Успешная аутентификация в тестовом приложении

Манипуляции с REST-интерфейсом


В связи с бурным развитием интернета и сервис-ориентированной архитектуры (SOA) все большую популярность набирают REST-решения. Так как большинство современных нереляционных СУБД организовано в соответствии с последними тенденциям в индустрии, то многие из таких систем либо сами реализуют REST, либо используют сторонние продукты для доступа к данным с помощью RESTful-архитектуры. MongoDB не исключение: в эту СУБД входит простой REST-интерфейс который позволяет получить доступ к данным в режиме «Только чтение». Кроме того, существует проект под названием Sleepy Mongoose, который реализует полную поддержку REST.
Давай посмотрим, как работает REST-интерфейс, встроенный в MongoDB. Сервер СУБД должен быть запущен с параметром "--rest". REST-сервис доступен по адресу http://127.0.0.1:28017/. Это очень простое web-приложение, которое отображает информацию о текущем состоянии СУБД и позволяет формировать запросы к базам данных. Вот несколько интересных ссылок:
  • /listDatabases?text=1 — список баз данных;
  • /serverStatus?text=1 — текущее состояние сервера.

В общем случае для формирования REST-запроса к базе данных используется URL следующего вида:

http://127.0.0.1:28017/база_данных/коллекция/?filter_поле=значение

На странице «Манипуляции с REST-интерфейсом» нашего web-приложения происходит аутентификация пользователя при помощи REST-интерфейса MongoDB. Она реализована в методе rest класса MongoDbController:

var restQry = "/secure_nosql/users/?filter_login="
               + login + "&filter_password=" + password;
var hash = restQry.indexOf("#"); 
if (hash > -1) {
  restQry = restQry.substring(0, hash);
}

Скрипт формирует REST-запрос, игнорируя при этом все данные после символа "#". Когда REST-запрос готов, скрипт формирует HTTP-запрос к серверу и ожидает результат в формате JSON. К примеру, запрос информации о пользователе root в базе данных secure_nosql выглядит следующим образом: http://127.0.0.1:28017/secure_nosql/users/?filter_login=root&filter_password=p@ssw0rd. Всё бы хорошо, но в коде есть ошибка, проявляющая себя при обработке символа "#". Если ты попробуешь войти с именем «root#», то окажешься залогиненным в системе. Проблема, обусловленная формированием следующего URL: http://localhost:28017/secure_nosql/users/?filter_login=root#&filter_password=. состоит в том, что параметр filter_password был проигнорирован и аутентификация проходила посредством запроса http://localhost:28017/secure_nosql/users/?filter_login=root.
Стоит отметить, что большинство REST-интерфейсов также уязвимы к подделке межсайтовых запросов (CSRF):

<img src="http://localhost:28017/secure_nosql/users/" />

Честно говоря, я довольно скептически отношусь к RESTful-архитектуре, так как она открывает большие возможности для злоумышленников. Постарайся не использовать REST. Но если без него никак, то предварительно прочитай статью Robust Defenses for Cross-Site Request Forgery, в которой очень подробно описаны все аспекты безопасности REST.

JavaScript-инъекции


Большинство современных реляционных СУБД позволяют создавать хранимые процедуры. Давай рассмотрим Microsoft SQL Server, который расширяет возможности ANSI SQL и позволяет соблюдать практически любые требования бизнес-приложений. Если тебе не хватает возможностей T-SQL (это диалект SQL, реализованный в SQL Server), то ты можешь написать хранимую процедуру на C# или любом другом .NET-совместимом языке.
MongoDB обладает не менее богатыми возможностями, в число которых входит серверный JavaScript. Фактически ты можешь выполнить почти любой код на сервере баз данных. С одной стороны, это позволяет писать очень сложные приложения для обработки данных, с другой — делает твое приложение более уязвимым.
Где можно использовать JavaScript в MongoDB?
  1. Запросы с оператором $where. Например, запрос db.orders.find({ $where: «this.amount > 3» }) вернет тебе список заказов, количество пунктов в которых больше трех.
  2. Команда db.eval. К примеру, db.eval(«function (x) { return x * x; }», 2) вернет четыре.
  3. Функции для сохранения в базе данных. MongoDB позволяет сохранять функции, написанные на языке JavaScript, в базе данных. Для этого используется специальная системная коллекция system.js. Чтобы создать новую хранимую функцию foo(x), выполни следующий код:

    	db.system.js.save( { _id: "foo", value: function (x) { return x * x; }})

    Теперь можешь попробовать вызвать ее вот так: db.eval(«foo(2)»).
  4. Map/Reduce. Map/Reduce — это программный фреймворк, разработанный компанией Google для параллельных вычислений над большими объемами данных. Он содержит две операции: map, используемую для предварительной обработки данных, и reduce, осуществляющую поиск результата.
    MongoDB позволяет запускать операции map/reduce на сервере баз данных. Операции по распараллеливанию процессов и агрегации СУБД берет на себя, от разработчика требуется лишь указать исходные данные и функции, реализующие команды map и reduce. Дополнительная информация доступна в документации на MongoDB.

В нашем тестовом приложении имеется JavaScript-инъекция в операторе $where и аналогичная уязвимость в команде db.eval.
Начнем c оператора $where. Открой приложение и выбери пункт $where в меню «Инъекции JavaScript». Аутентификация на странице реализована в методе ssji-where класса MongoDbController:

var js = "this.login === '" + login + "' 
          && this.password === '" + password + "'";
var loginParam = { "$where" : js };

Сначала генерируется скрипт, который проверяет имя и пароль пользователя. К сожалению, данные в переменных password и login никак не проверяются, что позволяет выполнить любой скрипт на сервере.
Теперь давай попробуем войти как root. Введи имя пользователя «root' //» и попробуй войти. Ты в очередной раз успешно залогинишься! Это возможно благодаря тому, что на сервере был сформирован следующий запрос к MongoDB:

{ '$where': 'this.login === \'root\' //\' && this.password === \'\'' }

"//" — это комментарий в JavaScript, поэтому результирующий запрос примет вид «this.login === 'root'».
К счастью, в момент выполнения запроса база данных находится в режиме «Только чтение», поэтому злоумышленник не сможет написать скрипт, модифицирующий твои данные. Но это еще не говорит о том, что подобная атака невозможна. Открой страницу «Инъекции JavaScript — db.eval(...)». На этот раз аутентификация происходит посредством вызова функции eval на сервере базы данных:

var js = "function () { return db.users.findOne ({ login: '" + login + "', password: '" + password + "' }); }"
db.eval(js);

Как видишь, у тебя есть возможность выполнить любой код на сервере БД. Попробуй создать нового пользователя pen_test с паролем pen_test. Для этого нужно ввести следующий логин:

'}), db.users.insert({login: 'pen_test', password: 'pen_test'}), 1 } //

Во-первых, ты вошел в систему. Во-вторых, в базе данных появился новый пользователь pen_test. :-)
Серверный JavaScript обладает огромным потенциалом и в то же время несет в себе много опасностей. Одна маленькая ошибка в коде, и злоумышленник получает доступ к твоему серверу баз данных. Я настоятельно рекомендую не использовать серверные скрипты: 85 % запросов можно написать и без них.


Доступ к тестовому приложению запрещен


Заключение


В заключение я бы хотел поговорить о том, каким я вижу настоящее и будущее NoSQL-сообщества. Во-первых, ты убедился в том, что NoSQL-СУБД пока не являются мейнстримом, но уже довольно близки к этому: появляются новые нереляционные СУБД и проекты, которые их используют. Как мне кажется, в ближайшем будущем NoSQL-решения займут относительно большую долю на рынке высоконагруженных приложений. Во-вторых, безопасность современных NoSQL-СУБД оставляет желать лучшего. Если в мире реляционных баз данных существует один стандартизированный язык запросов — SQL, то в «нереляционном мире» каждый реализует язык запросов, как ему вздумается: JSON, XQuery, REST-интерфейсы. Соответственно, и потенциальных уязвимостей намного больше. Если при работе с реляционными базами данных было достаточно изучить SQL-инъекции и способы борьбы с ними (при этом ты мог применить уже имеющиеся знания как в MySQL, так и в Oracle или SQL Server), то с нереляционными базами данных всё не так просто. Сначала тебе предстоит разобраться, какой язык запросов используется в твоей СУБД, как осуществляется доступ к данным и существуют ли дополнительные возможности, которые можно использовать для взлома (например, серверный JavaScript в MongoDB). После сбора информации тебе предстоит найти потенциальные уязвимости в своей системе и способы их устранения.

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


FAQ по NoSQL


Q: Каково происхождение термина NoSQL?
A: NoSQL переводится не как «Нет SQL» (No SQL at all), а как «Не только SQL» (Not only SQL). Этот термин возник в 1998 году: именно так Карло Строцци (Carlo Strozzi) назвал свою нереляционную систему управления базами данных. Второе рождение он получил в 2009-м, когда Эрик Эванс (Eric Evans) на конференции, посвященной свободным распределенным базам данных, использовал его для обозначения нереляционных СУБД и хранилищ данных. Можно считать, что именно эта конференция положила начало буму NoSQL-решений.

Q: Что такое MongoDB?
A: MongoDB — это документо-ориентированная система управления базами данных с открытым исходным кодом, разрабатываемая компанией 10gen с октября 2007 года. Первый релиз MongoDB вышел в феврале 2009 года. СУБД позиционируется как решение для хранения данных в высоконагруженных проектах. К ее основным достоинствам можно отнести высокую производительность, отличную масштабируемость, отказоустойчивость и наличие обширного сообщества разработчиков и пользователей. На данный момент среди пользователей MongoDB присутствуют такие всемирно известные компании, как Disney, SAP, Forbes и другие.

Q: Почему NoSQL?
A: Давай рассмотрим, какие основные преимущества имеют базы данных NoSQL по сравнению со своими реляционными собратьями.
  1. Производительность.Разработчики большинства NoSQL-решений посвящают очень много времени оптимизации своих проектов. MongoDB позволяет добиться порядка 20000 вставок и 4800 выборок в секунду.
  2. Простая настройка репликации баз данных. MongoDB позволяет настроить репликацию всего лишь с помощью нескольких команд, то есть гораздо проще, чем в том же Oracle.
  3. Множество «плюшек», облегчающих жизнь программистам. Например, MongoDB имеет встроенную поддержку Map/Reduce и сложных структур данных.
  4. Масштабируемость. Это один из главных козырей NoSQL-СУБД. Большинство из них поддерживает горизонтальное масштабирование, что способствует существенной экономии средств на оборудовании, ведь дешевле купить еще один недорогой сервер для кластера, чем добавить в корпоративный сервер дополнительную пару процессоров и оперативную память.
  5. Они дешевле! Большинство NoSQL-решений — это проекты с открытым исходным кодом. Ты можешь скачать их прямо сейчас и начать использовать. Вокруг многих проектов сформировалось большое и сплоченное сообщество, которое всегда готово помочь и исправить найденный тобой баг. В конце концов, ты сам можешь исправить баг или написать необходимое расширение. Кроме того, можно заметно сэкономить на расходах на администраторов баз данных, так как нереляционные СУБД гораздо проще реляционных и для их поддержки в большинстве случаев не требуется специальный сотрудник.

Q: Кто использует NoSQL?
A: Как видишь, NoSQL-СУБД имеют ряд неопровержимых преимуществ. Давай рассмотрим, кто же их использует:
  • «Облачные» сервисы, а именно Google, Amazon и даже Windows Azure от Microsoft.
  • Порталы и социальные сети: Facebook, Twitter, LinkedIn — думаю, ты сможешь продолжить список самостоятельно.
  • SaaS. Всё большее число компаний выбирает решения Software-as-Service в качестве основной платформы для ведения бизнеса в тех отраслях, где постоянно растут нагрузки на инфраструктуру. Многие поставщики SaaS-решений переходят на NoSQL. Так, к примеру, поступил Salesforce.com — лидер в области SaaS CRM.
  • Стартапы. Это отдельная категория проектов, которые запускаются с минимальным бюджетом с расчетом на суперприбыли в будущем. Такие проекты часто выбирают NoSQL-решения, так как они, во-первых, дешевы, а во-вторых, представляют собой отличный задел на будущее, если проект станет популярным.


image
Журнал Хакер, Февраль (02) 157
Илья Вербицкий (blog.chivavas.org)


Подпишись на «Хакер»


Автор: @gorl

Комментарии (52)

  • НЛО прилетело и опубликовало эту надпись здесь
  • +29
    Не знаю почему, но очень не нравится, когда в статье идет обращение на «ты».
    • +18
      это стиль журнала какер. У них довольно частенько бывали статьи вида: «Привет, мой юный друг какер»
      • +2
        Лишнего панибратства уже лет пять как нет :). А вот обращение на «ты» — это да, особенность журнала.
        • 0
          Ну не в «гостях» же…
      • +1
        Логично заметить, что стиль журнала можно оставить при журнале, а делать копи-пасту на другой ресурс где есть свой стиль не стоит, ИМХО.
    • 0
      Наверное потому, что вам не 18 лет.
  • +25
    Да уж, кто будет писать query сравнения пароля по regexp?
    Я и на equal не советую переписывать, надо поднимать юзера по логину и уже на сервере сравнивать пароль, тем более если есть шифрование.
    Даже как пример в статье это выглядеть крайне глупо.
    • +2
      Я был в шоке от таких примеров.
    • 0
      может для автора это и норма но для меня нонсенс
  • +13
    Статья с грозным заголовком, суть которой, как и обычно, проблемы реализации фронт-эндов/бэк-эндов, которые с БД работают, и безопасности при работе с данными в них, а ни сколько не самой БД.
    • 0
      Довод принят. Название пофиксили
  • +21
    Писец, сами выдумали проблемы, сами же героически их решили.

    Ни одна из этих «уязвимостей» в реальном мире просто не встречается :)
    • +1
      Но писать же о чем — то надо :)
    • +2
      Цель материала — показать уязвимости, связанные с использованием NoSQL баз данных. Пускай на базовом уровне. Если вы считаете, что все разработчики заботятся о фильтрации входящих данных, то, увы, вы ошибаетесь :(. Друзья из Positive Technologies и Digital Security не дадут соврать.
      • 0
        Не дадим. Разработчики, конечно, разные, но быват в этой жизни абсолютно все, поэтому такой подход как бы предупреждает: и тут подобные проблемы есть, будьте начеку 8)
      • +1
        и что же они не дадут соврать?
        showcase из реальной жизне? где mass assignment в nosql?
  • +4
    Бред какой-то
  • –3
    Неужели журнал хакер сменил аудиторию на школьников? Правда сложно писать серьезные вещи? Это далеко не всем дано, я бы даже сказал еденицам.
    • 0
      ксакеп уже как ~10 лет не торт.
      • +3
        скучаете по delphi, обзору игр и настройке irc-бота?

        если будет желание, сравните контент номеров:
        www.xakep.ru/magazine/xa/041/default.asp (10 лет назад)
        www.xakep.ru/magazine/xa/160/default.asp (последний номер)
        • +1
          Дело не в сожержании а в содержимом. У них бывали статьи с очень громким и интересным названием, но полные воды.
          • 0
            Статьи в Х зависят от авторов. Разные авторы разные статьи. Журнал фактически «опен сорс». Каждый может написать туда, что хочет 8)
            • 0
              Я просто думал что у них там серьезный фейсконтроль контроль статей и авторов. Оказывается я сильно ошибался =)
              • 0
                Ну фейс-контроль есть. Статьи типа «брутим» аськи или делаем фейк для ВКонтакте не пройдут. Данная статья, возможно, спорна, но тема интересна в общем, и даже описанные кейсы эксплуатации интересны для общего представления потенциала.
                • 0
                  var regexpPwd = new RegExp("^" + password, «i»);
                  var loginParam = { login: login, password: regexpPwd };

                  после этого уже стало смешно :)
                  тема да, интересная, но подача материала из серии 'вредные советы', такого кода как описывает автор, даже школьники не пишут, я уж не говорю о более опытных, которые даже в похмелье в 5 утра такое не напишут.
                  • 0
                    шит хеппенс. я однажды видел на реальном проекте такое:
                    select… from user_table where user_table.login like $login and user_table.pass like $pass;
  • 0
    Поправьте ссылку на «тестовый web-сайт»
  • +1
    >объектно-ориентированные базы данных (db4o, Cache, Jade);

    мне кажется Cache регулярно относят к объектной СУБД только те люди которые с ней никогда не работали
    да там есть поддержка объектной парадигмы БД там есть также поддержка реляционной парадигмы БД — но весь вкус этой СУБД в использовании — древовидных БД с помощью прямого доступа — не объекты — не SQL — а деревья! Да это труднее — да это требует больше времени — но только там можно получить скорость быстродействие и гибкость в полной мере… (наболело)
  • +12
    Зашел, думал что-нибудь смачное будет, а тут один индусский код, который еще надо постараться написать.

    • Проверять пароль регуляркой это конечно пять. Как минимум потому-что никто в своем уме не будет хранить пароль в открытом виде. И вообще, вы же сами написали, "поиск с помощью регулярных выражений", проверять равны ли две строки посредством регулярок, эм, это даже не смешно.

    • И еще одна высосанная из пальца дыра. Черт возьми, как же можно догадаться делать eval что-бы сделать запрос. Кажется этот пункт можно переформулировать в «Нету дыр как в MySQL? (Я о генерации запросов методом подстановки, если что) Так давайте сделаем так, чтобы они были!». Ибо все нормальные люди сделают этот код так:
      users.find_one({'login': login})
      

    • Господи, запустили сервер с --rest и теперь его можно поломать через него! Серьезно, это как дать гранату мартышке, а потом удивляться салюту из кишок. В документации MongoDB даже указано, что рекомендуемый способ использования это без аутентификации, но при этом разрешаем файрволом только оттуда, откуда можно, а следовательно CSRF сразу идет лесом. Ну а пихание данных без проверки, смотреть предыдущий пункт, намеренно использовать потенциально дырявую штуку, а потом кричать «решето!» весьма странно.

    • А авторизация посредством выполнения JavaScript, вот кто так напишет? Да, правильный ответ — никто. Основной юзкейс этого дела, это посчитать что-то сложное прямо на сервере, чтобы не таскать данные туда-сюда. И то, в новой MongoDB будет интересная штука чтобы делать все это без JS.


    Во-вторых, безопасность современных NoSQL-СУБД оставляет желать лучшего.
    Вообще, сказали бы честно, уровень развития мозгов некоторых разработчиков оставляет желать лучшего, такие примеры как тут есть лютый индусизм (т.е. абсолютное не понимание инструмента).
    • +4
      SQL-инъекции тоже только в говнокоде бывают, и что? :)
      • 0
        просто за NoSQL садятся уже люди немного выросшие из plain-SQL запросов в коде и на различном опыте наученные
    • 0
      Про то что никто не хранить пароли в открытом виде, вы так неправы ;(
    • 0
      молодец прогер, вс еверно
  • 0
    Постоянное «ты»-канье в статье как-то коробит. Так и слышится «здддддравствуй, мой маленький друг, сегодня я расскажу тебе сказочку о волшебном ноэскуэль...».
  • НЛО прилетело и опубликовало эту надпись здесь
  • +1
    статья конечно кажется бредом, и я полагаю что, как и в данном случае нужно еще постараться написать так чтобы инъекция стала возможной.
    но в качестве примера для попыток взлома могу предложить поиграть с InterSystems Cache, думаю написать там код подверженный инъекциям будет сделать сложнее, конечно если использовать именно NoSQL доступ к данным а не sql.
  • НЛО прилетело и опубликовало эту надпись здесь
    • –1
      Реакция оправданна, это статья-ответ на несуществующую проблему. Автор сначала философствует на отвлеченные темы, потом предполагает, как будет писать говнокодер и дает какие-то странные советы.
  • +1
    Map/Reduce. Map/Reduce — это программный фреймворк, разработанный компанией Google для параллельных вычислений над большими объемами данных.


    О да.

    www.cs.cmu.edu/Groups/AI/html/cltl/clm/node143.html
    X3J13 voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION)
    • +1
      Эту поделку в промышленных масштабах кто-то использовал?

      Я тоже впервые услышал про M/R когда Google начала расказывать о том как они его используют…
  • 0
    >MongoDB использует в качестве языка запросов BSON
    Не совсем корректно. BSON это нотация (Binary JSON), а не язык. А языком для запросов является JS.
  • 0
    Примеры искусственные, но дают повод задуматься об этом аспекте безопасности тем, кто не задумывался по причине «да ладно, у меня же нет sql».
    Так что спасибо автору.

    p.s. маленькое занудство: «но СУБД не может обойтись без языка запросов» — например, в CouchDB нет языка запросов. Есть REST-API для запросов, но в запросах просто передаются параметры, а не какие-либо логические конструкции.
    • +1
      Я приблизительно о том же. Ничто не мешает так же делать в любом другом случае. Сайт имеет досбуп к черным ящикам вызова процедур СУБД. Понятно что в процедуре тоже можно найти дырку, но написание перехвата ошибок в параметрах вызываемой функции и контроль формата параметра это первый курс, второй семестр. В том смысле что чем проще функции — тем сложнее в них чтото сломать.
  • +2
    Всетаки странно. Неужто никто не использует аутентификацию через хранимые процедуры? (Они вроде и в монго есть: Stored Javascript).
    Я, конечно не сайт девелопер, но когда приходится кропать под веб — у меня сайт только вызывает процедуры и функции с четко обозначенными правами — никаких запросов.
    Может быть сильно параноидально так делать или я в принципе неправильно подхожу к задаче, может укажете в чем ошибочность моего подхода? (а то долго думал — недостатков не придумал)
    • 0
      Сложно мигрировать между БД и сложно поддерживать.
      В mysql можно, случайно, снять дамп и забыть указать там «и сохрани мне все процедуры, функции и триггеры».

      Но и плюсы у этого подхода тоже отличные. Когда нужна параноидальная безопасность (финансовая сфера, например), то делать как-то иначе даже странно.
      • 0
        Я такой подход больше в MSSQL использовал. Просто когда читаешь примеры по книжке (я с этого начинал), там постоянно упоминалось о том что сторонние приложения ни в коем случае не должны тыкать запросиками напрямую в саму базу, а исключительно через хранимые процедурки, да и то — у каждой процедурки (или группы процедурок) должен быть свой юзер которому за пределы функционала процедуры даже тройным прыжком с переворотом не вырваться. (Для примера. Есть функция которая по логину и паролю дает человеку id сессии, используя промежуточную процедуру которая на основании логина и пароля дописывает в хэш таблицу сессий адрес, session_id и результат аутентификации. То есть если вы пробьете функцию сбора данных за ней остается функция которую может вызвать только функция сбора данных и никто больше — и в генератор сессии вы ничего не подсунете).
        А на тему галочки в дампе, так ведь можно и в бане раздеться забыть, но у воспитанных людей в трезвом виде такое не случается.
  • +2
    Автор забыл указать, еще один уровень — это абстрагирование, маппинг на объекты позволит автоматом избавиться от выстрела в ногу.
  • 0
    кстати в руби ^[a+z]+ лучше не использовать, дыра
  • 0
    new RegExp("^" + password, "i");
    Теперь я понял, откуда у этого издания такая репутация :)
  • 0
    У меня предложение журналу «Хакер»: помимо печати самой статьи, выкладывайте и комментарии с хабра — они частенько полезней самой статьи.
  • 0

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка