LINUX.ORG.RU

Прямой SELECT из Web-сервиса

 , ,


1

3

Есть некий веб-сервис, написанный на ... неважно, а то флейм будет, предоставляющий REST через http. С insert/update/delete в принципе все понятно, они контролируются логикой приложения, а вот с select все сложнее - клиентам необходимо делать сложные выборки со вложенными подзапросами, бешеными джойнами, группировками, аггрегацией и т.п. Причем разнообразие таких запросов обещает расти.
Задумался на тему нужности изобретений и маппинга возможностей SQL на JSON/URL-query, и очень мне не хочется все это делать.
А что если сделать так:
* создаем пользователя БД, который имеет права только на чтение некоторых таблиц определенной БД и все
* клиенты сервиса формируют SQL-запрос целиком, т.е. «select ... join ... where .. group by ... etc» и отправляют его строкой на сервис
* сервис выполняет его напрямую на БД от имени вышеуказанного пользователя
* результаты форматирует и отправляет клиенту

Насколько это будет безопасно/криво? С точки зрения скорости разработки/производительности - офигенно по-моему.
По безопасности - для таких запросов БД read-only, кроме того, можно на каждую таблицу создать VIEW, и дать доступ только к нему (таблицы запретить), а на уровне VIEW контролировать права доступа на чтение каждой строки (ACL определяемый приложением, не БД).
Еще хотелось бы насильно насаждать LIMIT x,y (в случае MySQL), чтобы нельзя было повесить всё запросом на миллионы строк (в проекте есть большие таблицы)

собственно вот. что скажут местные аналитики?

★★★★★
Ответ на: комментарий от umren

куча постоянно меняющихся параметров, код запросов тоже чувствую будет частенько меняться - неохота вылавливать несоответствия API сервера и клиента. даже дело не сколько в постоянной разработке, сколько в том, что код самих запросов довольно динамичен, в ХП он плучится только через eval строкового выражения, что есть кривизна

кроме всего прочего, использование ХП в данном случае никаких профитов не несет.

dib2 ★★★★★
() автор топика
Последнее исправление: dib2 (всего исправлений: 1)

Насколько это будет безопасно/криво?

Кривее не придумаешь. Если даже не рассматривать вопросы с безопасностью, то что будешь делать когда понадобится немного поменять схему БД? А с таким говнокодерским стилем разработки это наверняка понадобится, т.к. не похоже чтобы у вас думали дальше одного дня вперёд.

mashina ★★★★★
()
Ответ на: комментарий от mashina

не-не, запросы формируются не жестким кодированием полей, схема данных представлена на клиенте в виде объекта.
кроме того - чем традиционные схемы проще в этом смысле? особенно если динамический язык или отсутствие ORM на сервере?

а вот о безопасности хотелось бы поговорить

dib2 ★★★★★
() автор топика
Ответ на: комментарий от zed_0xff

ну об этом и речь. обертка в http для тех клиентов, которые ничего другого не могут (браузер+JS)

открывать порт - глупость, т.к. в том же мускуле бывают и уязвимости

dib2 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

ну это не про сабж, там ORM присутствует.
за остальных не расписываюсь, хотя знаю что есть любители SQL-лапши в коде.

dib2 ★★★★★
() автор топика

Подойди с другой стороны. Если пользователь формирует сложный запрос, со 100500 объединениями таблиц и сортировкой по неиндексированным полям, то браузер отвалится раньше по таймауту, чем он получит результат. Лучше заведи типа «заказать отчёт», который будет выполняться неизвестное время.

А пользователю предъяви что-то типа сообщения «принято к обработке. если вас не устраивает скорость автоматической обработки закажите шаблон отчёта»

ziemin ★★
()
Последнее исправление: ziemin (всего исправлений: 2)
Ответ на: комментарий от dib2

хема данных представлена на клиенте в виде объекта

Так схему не моментально же на клиент отдаёшь? Навряд ли сможешь поддерживать одновременно две рабочих схемы, это тупо труднореализуемо. А держать несколько версий API легко.

а вот о безопасности хотелось бы поговорить

Минимум можно будет легко заDoS'ить базу составлением определённых запросов. Простые анализы на LIMIT и т.п. не помогут от этого защититься. Возможность порезать всё ненужное для SELECT'ов тоже сомнительна, у SQL СУБД есть много служебных потрахов через которые можно получить некие данные, которые могут помочь злоумышленнику.

mashina ★★★★★
()
Ответ на: комментарий от dib2

открывать порт - глупость, т.к. в том же мускуле бывают и уязвимости

по определению в вашем велосипеде уязвимостей будет N+M, где M - это число уязвимостей в мускле.

zed_0xff
()

У нас такое есть, но только в тестовом режиме работы приложения. В прод такое не выставляем. А почему бы не положить запросы в файлик? И вызваать только те, которые лежат в файлике.

vromanov ★★★
()

проблема с правами доступа на таблицы, которые содержат общие/смешанные данные. если уж хочется подобной простоты, то можно разработать некоторое sql расширение, которое ты потом будешь транслировать в прямой sql.

наподобе

select * from documents where CABINET('/user_name')
это запрос транслируется в безопасный запрос аля
select * from documents d where d.cabinet_id = user_name_cabinet_id and d.user_permit in (select permit from user_permit where user_name=current_user)
Это относительно удобно и безопасно, но, возможно, будет не просто реализовать.

vtVitus ★★★★★
()
Ответ на: комментарий от vtVitus

Это примерно настолько же безопасно, как безопасно генерировать лапшой sql запросы, т.е. без возможности делать sql-инъекции.

mashina ★★★★★
()

Каждый раз когда мне казалось что задача сформулированна именно так как ты говоришь, оказывалось что запросы ну уж не совсем такие и разнообразные

vertexua ★★★★★
()

Скажут, что при проектировании забили на часть про предоставление инфы клиентам и теперь начинаются костыли.

Скорость разработки - конечно офигенно, ты ж ничего не хочешь разрабатавать.

Когда «вырастет разнообразие»? Вырастут ли при этом объёмы и не случится ли так, что на фоне затрат на переезд и масштабирование написать больше готовых запросов окажется некритично?

При неясном будущем управление правами и дополнительная нагрузка для вьюх и т.п. ложатся на нагруженную(?) БД. Будут проблемы с управлением правами, будут плодиться костыли для «безопасности».

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

anonymous
()

* клиенты сервиса формируют SQL-запрос целиком, т.е. «select ... join ... where .. group by ... etc» и отправляют его строкой на сервис

instant fail

ritsufag ★★★★★
()

собственно вот. что скажут местные аналитики?

Не к ночи будь помянут, но такое реализовано в MS'овском OData. Причём, вроде, существуют OSS реализации серверной части на Java (и не только), но я затрудняюсь сказать, в каком они состоянии. Реализацию клиентской части можно найти в Jaydata.

С другой стороны, OData это скорее костыль для языков без нормальной поддержки Lisp'a^W некоторых полезных языковых конструкций. Если ты пишешь сервак, скажем, на Clojure, то немного поколдовав с EDN можно будет творить чудеса безо всяких Ъ-Ынтырпрайзных фреймворков.

Насколько это будет безопасно/криво?

Зависит лишь от твоей кривизны рук.

runtime ★★★★
()

Отвечу на сей сумасброд вот этим моим постом от мая 2006 года

Внимание! :-)

почитай каменты, может чего умного для себя подчерпнешь )))

Deleted
()
Ответ на: комментарий от Deleted

хоть я и пришел к комбинации мнений товарищей vromanov и vertexua, можно свободно поговорить на тему :))

подчерпнул для себя ровным счетом ничего, кроме «ОЛОЛО, быдлокод» и прочие бугурты, вызванные разрывом стабильно-консервативных шаблонов трудящихся.

1. сабж не о веб-сайте, сабж о веб-сервисе. клиент - не обязательно веб-сайт.
2. я говорил немного о другом случае, чем по ссылке на скрин - т.е. не тупые строки запросов в html, а в традициях mvc, с раздельным кодом, с моделькой (схему которой выдает тот же сервис), параметры запроса диктует вью/контроллер (настраивается юзером) и т.д.
3. из реальных проблем вижу только неиндексное обращение, что теоретически может положить БД.
4. по безопасности - контроль на уровне БД и VIEW (и с производительностью это не имеет никаких пробелов, в сравнении с «традициями» - там тоже надо контролировать доступ, тот же WHERE ... VIEW даже профит может дать, если СУБД достаточно «умна»). От переполнений буфера в самой БД «традиции» тоже защищают не на 100% (да и вообще - это дела ОС и админа - не надо пользовать дырявые сервисы, в независимости от архитектуры - верно?). А багов в ACL к данным можно с одинаковым успехом наклепать как с одним, так и с другим подходом.

профитов тоже конечно не так уж и много: уменьшение кол-ва кода middleware => меньше ошибок, выше производительность, т.к. не надо заново изобретать то, для чего есть SQL. Особенно касается хитрых джойнов, поля которых пользователь может себе «заказать» при обращении к сервису.

идем дальше - известно 100500 решений (как правило интранет конечно), которые вообще напрямую к БД подключаются (1С?) - и ничего, работают.

так вот, есть ли еще какие веские доводы против, окромя вышеперечисленных, «ОЛОЛО ГОВНО» и спорного вопроса по поводу геморности поддержки решения?

;)

dib2 ★★★★★
() автор топика
Ответ на: комментарий от dib2

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

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

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

2. ты раскрываешь структуру своей БД, а это значит, что позволяешь клиенту слать хер знает какие запросы к БД (пусть даже и в режиме чтения, т.е. только селекты) - тебе рассказать к чему приведет запрос select * from table1, table1, table1? это называется декартово произведение. проще говоря, любой всяк сюда входящий поставит раком твою базу.

3. ты раскрываешь структуру своей БД, а это значит, ты сильно упрощаешь жизнь всяким взломщикам, которые «если не здесь, то там» найдут бреш и занунут тебе инъекцию на drop database с учетом типа БД (мускули, ораклы, постгресы и тд), их версий и тд

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

Навязывать мнение нет нужды. Просто хочется предостеречь от лишних шишек.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

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

совсем нет. в оппосте идет речь о веб-сервисе. это его задача - выдавать данные, обсуждается лишь метод формирования одного из API-вызовов. на скрине - SQL код в <script> в одном файле с HTML-разметкой, отрендеренной на базе полного SQL-запроса из формы - не надо это сравнивать.

1. ты раскрываешь структуру своей БД, а это значит, что ты делаешь зависимым свой клиентский код от структуры

1. давайте положим руку на сердце и признаемся, что в 80% абстракций дублируется низкоуровневая модель.
2. в любом случае клиент должен хоть что-то знать о том, с чем он работает, и т.к. модель диктуется ему с сервера, познания клиентского кода о структуре получаются как раз крайне поверхностными, известными только в runtime, что есть хорошо. грубо говоря, только очень мощный рефакторинг модели ударит по клиенту, а мелочи проглотит и так. Еще раз - речь не идет о тупом хардкодинге селектов на клиенте вместо сервера, селекты генерируются, избавляя от необходимости изобретать SQL в JSON/URL query.
3. при формировании сущностей более высокого уровня над БД никто не мешает оформить это отдельными вызовами, по всем канонам, за что так все ратуют. никто же не мешает. Можно даже подумать на тему общего API к объектам разных уровней.

2. ты раскрываешь структуру своей БД, а это значит, что позволяешь клиенту слать хер знает какие запросы к БД

это проблема, я о ней в курсе, все выше по треду.
кстати, традиционное API, написанное без включения мозга тоже может привести к подобным результатам.
Реально в такие минуты задумываешься о server-side рендеринге и «конём его всё». Но нет, задача не та.

которые «если не здесь, то там» найдут бреш и занунут тебе инъекцию на drop database с учетом типа БД (мускули, ораклы, постгресы и тд), их версий и тд

пользователю БД разрешен лишь select и то не везде. вероятность появления бреши такая же, как и вероятность SQL injection в традиционном подходе (если не меньше, учитывая широту охвата кода СУБД и веб-сервиса написанного полуторами говнокодеров). Особенно со всякими новомодными nodejs, где люди опять повально конкатят строки для мускуля (не поверишь, но буквально намедни разбирал одну такую писанину от аутсорсника - инъекция не сработала только потому, что нодовский драйвер не умеет ряд запросов за один exec(), но у него это в todo :))

4. ты не слышишь, что тебе говорят остальные, не хочешь внять даже очевидные вещи,

бла-бла-бла. тред о том чтобы «а поговорить?» - так почему бы и не разобрать по запчастям один, хоть и спорный подход. если бы я был невменяем, то тред не создавал бы, а говнокодил бы в две дырки. Почему не обсудить, а не сразу броскими фразами козырять?

dib2 ★★★★★
() автор топика
Ответ на: комментарий от Deleted

Навязывать мнение нет нужды. Просто хочется предостеречь от лишних шишек.

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

dib2 ★★★★★
() автор топика

Все накинулись потому что решили, что клиент может быть кто угодно. В закрытых решениях, аля B2B такое делать можно, потому что риск не особо велик. БД же каждый день бэкапится, не? :) Также неплохо все логировать.

Если требования безопасности высокие, то это ССЗБ. Проблема даже не в том, что нагрузка будет высокая, грохнут БД и похерятся данные. Проблема в том, что это потеря время на восстановление, раз. И два, отношение клиентов к вашему продукту будет негативным. А при присутствии хороших конкурентов твоя контора разорится.

Вобщем, ничего страшного. Делай так как можешь. Потом как начнутся «полеты» будешь их разбирать и переделывать.

gh0stwizard ★★★★★
()
Ответ на: комментарий от gh0stwizard

В закрытых решениях, аля B2B такое делать можно, потому что риск не особо велик.

собственно да, это интранет сервис. но не суть

Если требования безопасности высокие, то это ССЗБ

скажем так, требования - стандартные, без фанатизма

Делай так как можешь.

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

dib2 ★★★★★
() автор топика
Ответ на: комментарий от feofil

смотрел, но у меня много реляционщины, и профит неясен

dib2 ★★★★★
() автор топика
Ответ на: комментарий от dib2

давайте положим руку на сердце и признаемся, что в 80% абстракций дублируется низкоуровневая модель.

кладу руку на сердце и ответственно заявляю, что твое убеждение крайне ошибочно... ну вот очень-очень крайне. ты это поймешь, когда возьмешься за какой-то большой и серьезный проект, ну или прочитаешь какую-нибудь книжку о проектировании (сейчас уйма статей с новомодными называниями а-ля «паттерны проектирования», или попробуй посмотри в сторону SOA).

Еще раз - речь не идет о тупом хардкодинге селектов на клиенте вместо сервера, селекты генерируются, избавляя от необходимости изобретать SQL в JSON/URL query.

вот еще раз... какая в ж*** разница, сгенеришь на лету свой запрос или захардкодишь на странице - суть ровно одна: ты предлагаешь общаться со своим сервисом на сиквеле.

кстати, традиционное API, написанное без включения мозга тоже может привести к подобным результатам.

это называется «контролируемая проблема» и ты сможешь ее исправить еже ли вдруг обнаружится кривой запрос. и поверь мне, будет лютая «тоска, печаль и попаболь», когда проблема будет некотролируемая.

4. ты не слышишь, что тебе говорят остальные, не хочешь внять даже очевидные вещи

бла-бла-бла.

очень показательная реакция на замечание, показывающая правоту замечания ))).

Почему не обсудить, а не сразу броскими фразами козырять?

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

PS: для себя буду считать задачу выполненой - показал наглядно, что так делать нельзя. дело твое, внять это или проигнорировать

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

А не факт, что без перепиливания вообще всего он сможет решить все проблемы. Ты, как профи-советчик, не учел ту вещь, что клиентскую часть пишет не ТС. Т.е. это ссзб по обстоятельствам.

У меня что-то подобное было. Выход только в том, чтобы сделать чтобы работало. Вариант переделать туеву тучу строк кода других людей мне нев удалось. Может ТС повезет.

gh0stwizard ★★★★★
()
Ответ на: комментарий от Deleted

кладу руку на сердце и ответственно заявляю, что твое убеждение крайне ошибочно... ну вот очень-очень крайне

больших - это каких? я конечно не джедай, но за плечами парочка «небольших» (~50 таблиц) и один большой (сотня, а сейчас уже наверное и больше). Большинство таблиц мапилось на логику «как есть», и никакого дискомфорта не ощущалось (собирать абстракции поверх просто не было необходимости, равно как и обратно - была возможность и необходимость делать это).

или попробуй посмотри в сторону SOA

что смотреть? для меня это и есть «традиционно». тут хотелось обсудить альтернативные подходы на одном участке API параллельно с SOA.

ты предлагаешь общаться со своим сервисом на сиквеле.

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

очень показательная реакция на замечание

ну так не надо относится ко всем как к нубам, если человек хочет обсудить с аналитиками что-то новое, это еще не значит что он нихера не знает.

показал наглядно, что так делать нельзя. дело твое, внять это или проигнорировать

чего кипишевать-то? спокойней надо быть, так тебе нервов на всех анонимусов не хватит :)
единственная уникальная и трезвая мысль это ««контролируемая проблема» и ты сможешь ее исправить еже ли вдруг обнаружится кривой запрос. и поверь мне, будет лютая «тоска, печаль и попаболь», когда проблема будет некотролируемая.», за что спасибо.
(собственно решение уже давно принято и без вас, опубликовано выше)

dib2 ★★★★★
() автор топика
Ответ на: комментарий от gh0stwizard

А не факт, что без перепиливания вообще всего он сможет решить все проблемы. Ты, как профи-советчик, не учел ту вещь, что клиентскую часть пишет не ТС. Т.е. это ссзб по обстоятельствам.

есть такое дело. т.е. с одной стороны надо быть многогранным/многофункциональным, и не писать по хендлеру на каждый чих, с другой - соблюсти рамки приличия и не делать сабж. Одни только 1С-ники чего стоят..

dib2 ★★★★★
() автор топика
Ответ на: комментарий от dib2

Ну тогда ты можешь на полном серьезе придти к своим коллегам и сказать: ребята, я тут подумал, а что если мы перепишем весь код с нуля? Предварительно у тебя уже должна быть в голове и на бумаге детально расписана новая архитектура, чем больше деталей тем лучше. Естественно на это уйдет у тебя недели две-три, не меньше. И еще лучше, если дело таки серьезное (в вопросах безопасности), то потрать еще пару месяцев на написание своей части кода и клиентского прототипа. Возможно дело выгорит. Плюс от этого будет один — научишься немного проектировать, это тебе пригодится.

Конечно, если тебе кажется, что это того не стоит, то думай сам. Советы тут тебе давали грамотные и честно говоря близкие к идеальному решению. Этого хочется всем, только реальность редко допускает такое.

gh0stwizard ★★★★★
()

Амигос dib2 постучись ко мне на почту. помоему у меня есть то что тебе надо.

ЗЫ почта в профиле.

MikeDM ★★★★★
()
Ответ на: комментарий от dib2

Если тебе интересно проектирование могу порекомендовать несколько книжек:

  • 97 этюдов для архитекторов программных систем (желательно)
  • Алан Купер об интерфейсе. Основы проектирования взаимодействия (необязательно)
  • Джоэл о программировании (необязательно)
  • Идеальная архитектура. Ведущие специалисты о красоте программных архитектур (желательно)
  • Мифический человеко-месяц, или Как создаются программные системы (обязательно)
  • Пионеры программирования. Диалоги с создателями наиболее популярных языков программирования (необязательно, но может быть интересно)
  • Поступай правильно! Как преданность работников приносит прибыль и постоянных клиентов (just for fun, может понравится)
  • Софт - отстой! И что с этим делать (необязательно)
  • Совершенный код (Макконнел, очень желательно)
  • Профессиональная разработка программного обеспечения (Макконнел, очень желательно)
  • Peopleware: Productive Projects and Teams (обязательно; русский перевод имеется, но я забыл как эта книга переводится)
gh0stwizard ★★★★★
()

вот так сделали мы

filters[0][field]:iobjectType
filters[0][op]:eq
filters[0][val]:2
и ещё вот так
filters[0][field]:x1y1x2y2z
filters[0][op]:in
filters[0][val]:49.200,53.400,49.300,53.500,13

TERRANZ ★★★★
()
Ответ на: комментарий от TERRANZ

ну у меня есть похожие рабочие сервисы (немного другой формат правда), спасиб.

dib2 ★★★★★
() автор топика
Ответ на: комментарий от gh0stwizard

хм, спасибо за подборочку, ставлю +1 и лайк)

dib2 ★★★★★
() автор топика

Вот топикстартера, похоже, разубедили, а меня - нет. Какие-то, простите, ламерские аргументы, вида «давайте напишем больше кода, так будет безопаснее».

Выпишу из треда контраргументы и опровергну их.

что будешь делать когда понадобится немного поменять схему БД?

Очевидно, view будут переопределены на новый лад. Нет проблемы.

отсутствует изоляция внутреннего представления сущности

Сущности изолируются через view или хранимки. Не надо только каргокульта изоляции, когда на каждую фигню пишут геттер просто потому что Так Положено. Ну допустим удалишь ты поле из таблицы, ну во вьюшке тогда это поле вычислишь/нулями забьёшь, юзеры и не заметят ничего.

ты раскрываешь структуру своей БД, а это значит, ты сильно упрощаешь жизнь всяким взломщикам

За security through obscurity надо вообще гнать из профессии.

Если пользователь формирует сложный запрос, со 100500 объединениями таблиц и сортировкой по неиндексированным полям

Вот это действительно может быть проблемой. Впрочем, самодельный REST-апи с возможностью хитрых выборок будет так-же или более уязвим. А если хитрые выборки юзерам не нужны, то можно написать фильтр, пропускающий только тривиальные запросы из правильных таблиц/вьюшек и правильными полями в where/sort.

legolegs ★★★★★
()
Последнее исправление: legolegs (всего исправлений: 1)
Ответ на: комментарий от legolegs

Вот топикстартера, похоже, разубедили, а меня - нет.

отнюдь. я просто не буду ставить это во главу угла, но на попробовать возьму (прикрыв такие сервисы авторизацией с повышенными правами - бетатестеры)


более того, нашел пачку подобных проектов (и соотв. срачей на тему) на php, java и даже C.

dib2 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.