Re[17]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.02.14 06:40
Оценка: 3 (1) +1
Здравствуйте, Cyberax, Вы писали:

C>Нет. Враг угадывает какой UUID будет у запроса create_new_user() от привиллегированного пользователя и использует этот UUID при создании пользователя под своим контролем.


Какая-то муть в квадрате.

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

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

Если так через одно место проектировать, то у вас это будет минимальной проблемой из всех.

C>Решения:

C>1) Сделать клиентский токен полностью алгоритмическим, включив туда ID пользователя и секретные данные. Так поступает, например, Amazon. Недостаток: сложность реализации, не всякий клиент может иметь доступ ко всем нужным HTTP-заголовкам.
C>2) Серверные тикеты с проверкой авторизации, включая возможность выдать сразу N тикетов.

3) выпрямить руки, pardon my french, и сделать так, чтобы от знания посторонним конкретного id ничего не ломалось.
The God is real, unless declared integer.
Re[17]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 06:45
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Сотню запросов с латентностью в 200-300 миллисекунд? Ну-ну.
Ничего не понимаю. Мы всё ещё про атомарное изменение пачки объектов? Я же говорю: делается 1 (один) PUT в объект transaction. Откуда взялась сотня запросов?

C>Код библиотеки на JS так не умеет.

Код какой библиотеки?

C>Нет. Враг угадывает какой UUID будет у запроса create_new_user() от привиллегированного пользователя и использует этот UUID при создании пользователя под своим контролем.

1. И каким образом враг может угадать, какой UUID будет у запроса create_new_user()?

2. Непонятно, почему вы не можете защитить протокол, разведя адреса пользователей по разным namespace. Грубо говоря, клиент 1 создаёт пользователей по адресам /client1/7a342ca2-e79f-528e-6302-8f901b0b6888, клиент2 — /client2/7a342ca2-e79f-528e-6302-8f901b0b6888. Вариант — каждый создаёт пользователей с идентификаторами типа username@domain.tld, где domain.tld принадлежат соответствующим клиентам и создать пользователя в чужом домене невозможно (так, например, работает Office 365).

C>Решения:

C>1) Сделать клиентский токен полностью алгоритмическим, включив туда ID пользователя и секретные данные. Так поступает, например, Amazon. Недостаток: сложность реализации, не всякий клиент может иметь доступ ко всем нужным HTTP-заголовкам.
C>2) Серверные тикеты с проверкой авторизации, включая возможность выдать сразу N тикетов.
Либо вы чего-то недоговариваете, либо вы не видите простых и очевидных решений простой проблемы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.02.14 06:48
Оценка: 15 (3) +1
Здравствуйте, dimgel, Вы писали:

J>>обращается по урлу www.example.com/api/users/F889A953B7C543AB82762A2E02E299BF


D>А вот меня кстати ещё с книжки смущает кодировать id|login|api_key текущего юзера в URL. Если мне, к примеру, не нужно между юзерами ничего шарить, т.е. они полностью изолированы друго от друга, я хочу юзать /my/contacts вместо /users/KEY/contacts (или вместо прилагательного my принято что-то другое юзать) + HTTP authorization (пишут ещё про какой-то OAuth, но мне в него лениво и наверняка он браузерами не поддерживается).


Если ты твёрдо контекстом определил, что есть "my", и по дороге нет посторонних участников, то проблем нет.

Но REST в описанном виде рассчитан в том числе и на участие промежуточных HTTP proxy с локальными кэшами (типа знаменитого squid, или nginx frontend). (Прокси не обязан быть публичным, он может быть и внутренним только для целей данного сервиса — но он всё равно может быть.) Предположим, что содержимое ответа /my/contacts не настолько секретно, чтобы не доверять его промежуточным автоматическим участникам. Как ты сделаешь различение, что есть /my/contacts для клиента 1 и /my/contacts для клиента 2? Прокси не в состоянии это различить. Максимум, что ты можешь — сказать ему не кэшировать. Но даже в этом случае прокси имеет право соптимизировать, если идут одновременные запросы на один и тот же URL от разных участников и один из ответов ещё не отдан до конца. Авторизация, согласно RFC 2616 и тому подобным, не влияет на кэширование.

А если ты отказываешься от хотя бы потенциального допуска промежуточных прокси — это становится уже не REST, а просто каким-то вариантом протокола типа дай/возьми.
The God is real, unless declared integer.
Re[18]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 06:49
Оценка:
Здравствуйте, dimgel, Вы писали:
D>А вот меня кстати ещё с книжки смущает кодировать id|login|api_key текущего юзера в URL. Если мне, к примеру, не нужно между юзерами ничего шарить, т.е. они полностью изолированы друго от друга, я хочу юзать /my/contacts вместо /users/KEY/contacts (или вместо прилагательного my принято что-то другое юзать) + HTTP authorization (пишут ещё про какой-то OAuth, но мне в него лениво и наверняка он браузерами не поддерживается).
Это — плохая идея. Есть такой набор стандартных "плохих идей", желание следовать которым нужно из себя выдавливать. В мире СУБД это желание иметь PK int indentity "без дырок"; в мире Web — иметь одинаковый адрес для разных данных. Это мешает всем встроенным инструментам: ответы на такие запросы нельзя кэшировать; минимальные ошибки конфигурации прокси могут привести к показу чужих данных; легко ошибиться, используя ссылку из одного контекста в другом контексте.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Jack128  
Дата: 10.02.14 06:52
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, Sinclair, Вы писали:


S>>>>Да хоть 1000 — принцип тот же.

C>>>Ну да, то есть никакого.
S>>Что значит "никакого"? Принцип — делаем PUT в объект "Transaction".
C>Сотню запросов с латентностью в 200-300 миллисекунд? Ну-ну.

C>>>Оказалось нужно различить PUT с дефолтными значениями и PATCH изменившихся.

S>>Не до конца понимаю. Это же ваш протокол, что мешало внести в него понятия (reset-to-default), (clear), (leave-as-is) в дополнение к установке конкретного значения?
C>Код библиотеки на JS так не умеет.

C>>>Если враг может сделать так, что для create_new_user() будет конфликт UUID'ов, то есть шанс подменить user_id на контролируемый врагом.

S>>Продолжаю не понимать. То есть вы хотите сказать, что клиент 1 (привилегированный) делает типа assign_roles(admin_role), а клиент 2 (непривилегированный) делает reset_password(), и всё это на один и тот же user_id?
C>Нет. Враг угадывает какой UUID будет у запроса create_new_user() от привиллегированного пользователя и использует этот UUID при создании пользователя под своим контролем.

C>Затем привиллегированный пользователь делает create_new_user() с этим же UUID'ом и ему попадает уже существующий пользователь, которого создал враг, так как для сервера это кажется просто повторением запроса из-за ошибки клиента.


А почему бы привилегированному пользователю просто не поверить, что ему возвращается 201?
Re[18]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 10.02.14 06:58
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Сотню запросов с латентностью в 200-300 миллисекунд? Ну-ну.

S>Ничего не понимаю. Мы всё ещё про атомарное изменение пачки объектов? Я же говорю: делается 1 (один) PUT в объект transaction. Откуда взялась сотня запросов?
Т.е. мы делаем PUT данных для всех объектов? Как?

C>>Код библиотеки на JS так не умеет.

S>Код какой библиотеки?
Что-то на основе Chaplin.

C>>Нет. Враг угадывает какой UUID будет у запроса create_new_user() от привиллегированного пользователя и использует этот UUID при создании пользователя под своим контролем.

S>1. И каким образом враг может угадать, какой UUID будет у запроса create_new_user()?
Ну вот программист-идиод на клиенте (которого мы не контролируем) использовал текущее время в качестве UUID'а. Или использовал random-UUID, но с предсказуемой последовательностью.

S>2. Непонятно, почему вы не можете защитить протокол, разведя адреса пользователей по разным namespace. Грубо говоря, клиент 1 создаёт пользователей по адресам /client1/7a342ca2-e79f-528e-6302-8f901b0b6888, клиент2 — /client2/7a342ca2-e79f-528e-6302-8f901b0b6888.

Это всё полумеры. Могут быть более сложные сценарии, например, если непривиллегированный пользователь пытается облапошить админа своего же домена. Типичный способ реализации идемпотентности с минимальными расходами — в БД записываем client UUID в поле в таблицу user, так что всё прекрасно сломается.

Или это могут быть не пользователи вообще, а другие чувствительные к безопасности объекты.
Sapienti sat!
Re[19]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 07:11
Оценка:
Здравствуйте, netch80, Вы писали:

N>Но REST в описанном виде рассчитан в том числе и на участие промежуточных HTTP proxy с локальными кэшами


Point taken, thanks.
Re[19]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 07:14
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Это — плохая идея. Есть такой набор стандартных "плохих идей", желание следовать которым нужно из себя выдавливать.


Выдавить-то не проблема, но для этого этот набор надо сначала знать.

S>В мире СУБД это желание иметь PK int indentity "без дырок"


Упс, первый раз слышу. Кто и зачем этого может пожелать? (Смутно помню стародавние срачи про производительность индексов, но мне это всё казалось слишком далёким от реальной жизни простых смертных.)
Re[19]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 07:18
Оценка: +1
Здравствуйте, Cyberax, Вы писали:

C>Типичный способ реализации идемпотентности с минимальными расходами — в БД записываем client UUID в поле в таблицу user, так что всё прекрасно сломается.


Эм... Мне кажется, этот способ глючный сам по себе: два одновременных одинаковых запроса (хотя бы с разных табов браузера) всё положат. Я тут обмозговываю полученную информацию, и прихожу к выводу, что если я не хочу GUID-ы в качестве PK, то остаётся только server-side генерация тикетов, причём отдельный журнальчик хранить — кому и для какой операции какой тикет сгенерирован. И подчищать в нём старые записи.
Re[13]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 07:32
Оценка: 6 (1)
Здравствуйте, Serginio1, Вы писали:
S> Ну вот я отправляю письмо. Должен ему присвоить какой URL в котом содержится ID этого письма, что бы при повторной посылке POST оно не отправлялось, а получался ответ который до меня не дошел.
Всё правильно, только при PUT, а не POST.

S> Так же и с GET если я запрашиваю справочник по ID то согласно idempotent мне по этому ID должен возвращаться всегда одни и теже данные.

Нет. GET — safe, это другое, чем идемпотентность.

S>Согласно этому определению

В русской вики, как обычно, чушь. Читать надо не её, а RFC 2616.

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

Такие проблемы возникают от непонимания протокола HTTP и того, как там работает кэширование.
Нужно выставлять корректные хидеры ответов, и корректно обрабатывать хидеры запросов. Тогда данные будут возвращаться те, что нужно.
S> Тогда я понимаю что бы избавиться от идемпотентности можно добавить GUID или метку времени в строку запроса?
Так делают в специальных случаях: например, т.н. вторичных запросов. Допустим, ваша веб-страница использует некую JavaScript библиотеку. Библиотека изменяется раз в никогда (например, раз в год), причём заранее предсказать дату её изменения невозможно. У вас есть две задачи:
1. Обеспечить максимальную производительность клиента и минимальную нагрузку на сервер, отдающий код библиотеки.
2. Обеспечить как можно более быструю замену библиотеки на клиентах при выходе новой версии
Эти задачи на первый взгляд друг другу противоречат: если поставить длинный expiration, то клиенты будут редко ходить за библиотекой, но при смене версии они продолжат работать с устаревшей. Если поставить короткий expiration (либо вообще положиться на conditional GET), то клиенты будут постоянно долбить сервер.
Решается предельно просто: версия библиотеки вшивается в URL, тело отдаётся с хидерами Expiration:never.
Теперь клиенты никогда не будут перезапрашивать библиотеку, а сразу будут брать её из кэша (экономия roundtrip time — около 100мс — на этапе загрузки страницы). Обновление библиотеки будет мгновенным — как только мастер-страница обновится, она укажет новый адрес библиотеки, и клиент немедленно скачает её в кэш.

Для первичных запросов такая техника не очень подходит. Дело в том, что при длинной экспирации нужен механизм оповещения об устаревании кэша. Во вторичных запросах механизм опирается на изменение src в основной странице, поэтому он прекрасно подходит для стилей, картинок, и скриптов. А для самой страницы такого механизма нет. То есть можно сделать мат в два хода: например, при запросе http://news.com/latest возвращать 302 Found на "последнюю" новость, отдавая location типа: http://news.com/2014/02/10/1788/.
Увы:
1. Большинство браузеров поменяют URL текущей страницы на переданный, так что последовательное нажатие F5 уже никогда не обновит страницу
2. При обновлении новостей придётся делать два запроса — что хуже, чем один с conditional get.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 07:47
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Решается предельно просто: версия библиотеки вшивается в URL, тело отдаётся с хидерами Expiration:never.


Я дописываю версию (а точнее, mtime и/или filesize и/или md5 — в зависимости от языка) в Query String.
Re[19]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 07:49
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Т.е. мы делаем PUT данных для всех объектов? Как?
Это вопрос к проектировщику протокола. Я же приводил пример с переводом со счёта на счёт: вместо 2х PUT на .../account1, .../account2 делается 1 PUT на /transactions/{id}/, а в теле указаны account1, account2, и сумма перевода.
Я не знаю специфики вашего протокола, и сценариев, в рамках которых нужно атомарно поменять 100 объектов. Знал бы — предложил бы решение.

C>>>Код библиотеки на JS так не умеет.

S>>Код какой библиотеки?
C>Что-то на основе Chaplin.
А почему не выбросить эту библиотеку и не написать свою? Кстати, если бы вы писали API на SOAP, то вам что, проще было бы? Есть какие-то JavaScript библиотеки с

C>Ну вот программист-идиод на клиенте (которого мы не контролируем) использовал текущее время в качестве UUID'а. Или использовал random-UUID, но с предсказуемой последовательностью.

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

C>Это всё полумеры. Могут быть более сложные сценарии, например, если непривиллегированный пользователь пытается облапошить админа своего же домена. Типичный способ реализации идемпотентности с минимальными расходами — в БД записываем client UUID в поле в таблицу user, так что всё прекрасно сломается.

Вы недоговариваете. Либо у вас какие-то конские требования к безопасности (но тогда вы огребаете и при RPC API в той же мере), либо у вас беспочвенные фантазии.
C>Или это могут быть не пользователи вообще, а другие чувствительные к безопасности объекты.
У всех чувствительных к безопасности объектов работают права доступа. Это и есть основной способ защиты от злоупотреблений. Сценарий конфликта идентификаторов приводит в REST к "кто последний, того и тапки", поэтому хитровывернутые пользователи, предсказывающие идентификаторы, просто теряют "свои" объекты.
Причинять ущерб себе самому — неотъемлемое право каждого идиота. Обязанность проектировщиков — дать нормальный способ избежать причинения ущерба, плюс обеспечить защиту от случайной ошибки.
В частности, сценарий с угоном пользователя не работает уже потому, что при PUT сбросится всё: и пароль, и емейл для password recovery, и набор прав. Поэтому всё, что получит злоумышленник — это authentication failed при попытке воспользоваться привилегированным аккаунтом. Если у вас не так — то это проблема реализации, а не REST.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 07:52
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Для первичных запросов такая техника не очень подходит. Дело в том, что при длинной экспирации нужен механизм оповещения об устаревании кэша. Во вторичных запросах механизм опирается на изменение src в основной странице, поэтому он прекрасно подходит для стилей, картинок, и скриптов. А для самой страницы такого механизма нет. То есть можно сделать мат в два хода: например, при запросе http://news.com/latest возвращать 302 Found на "последнюю" новость, отдавая location типа: http://news.com/2014/02/10/1788/.

S>Увы:
S>1. Большинство браузеров поменяют URL текущей страницы на переданный, так что последовательное нажатие F5 уже никогда не обновит страницу
S>2. При обновлении новостей придётся делать два запроса — что хуже, чем один с conditional get.

Ctrl+F5 рулит, гыгы.

Ещё можно сделать всё на ажаксе, а в корень прогружать пустую bootstrap-страницу.

А вообщеЮ в HTTP кеширование несколько противоестественное, потому что решение принимает клиент, который может вообще игнорировать заголовки сервера, причём в обе стороны: Ctrl+F5 чтобы всегда грузить, или вон system.console со своей Оперой (на редкость беспредельничающий браузер, и был таковым с самого начала: "ускорение загрузки" за счёт наплевательского отношения к протоколу).
Re[20]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 10.02.14 08:05
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Т.е. мы делаем PUT данных для всех объектов? Как?

S>Это вопрос к проектировщику протокола. Я же приводил пример с переводом со счёта на счёт: вместо 2х PUT на .../account1, .../account2 делается 1 PUT на /transactions/{id}/, а в теле указаны account1, account2, и сумма перевода.
Так и где здесь REST? Вижу обычный RPC.

C>>Что-то на основе Chaplin.

S>А почему не выбросить эту библиотеку и не написать свою? Кстати, если бы вы писали API на SOAP, то вам что, проще было бы? Есть какие-то JavaScript библиотеки с
SOAP был бы проще, уже почти жалеем, что не выбрали его. Заодно меньше проблем с валидацией схемы данных с ним.

C>>Ну вот программист-идиод на клиенте (которого мы не контролируем) использовал текущее время в качестве UUID'а. Или использовал random-UUID, но с предсказуемой последовательностью.

S>Непонятно, почему вас это волнует, а то, что идиод может использовать один и тот же пароль для всех пользователей — нет.
Авторизацией занимаемся мы сами, идиод будет получать только специальный токен.

S>Непонятно, почему вы думаете, что существует программист, настолько умный, что его не устроит штатная реализация UUIDCreate(), но настолько тупой, что своя реализация будет предсказуемой. Непонятно, каким образом злоумышленник суммет получить доступ к коду этого клиента, чтобы найти уязвимость.

Клиент — на JS.

Не веришь, что бывают уязвимые GUID'ы? Вот пожалуйста, почитай тред на SO: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript — ВСЕ примеры оттуда уязвимы чуть менее, чем полностью (Math.random() — криптографически небезопасен).

S>В общем, либо вы чего-то недоговариваете, либо у вас беспочвенная паранойя. Нужно понимать, что уязвимости клиента вы в любом случае не контролируете (кроме случая, когда клиентом является ваш же веб-сайт), поэтому вам нужно сосредоточиться на том, как дать API, позволяющий безопасную реализацию клиента. Реализовать API, запрещающий реализацию небезопасного клиента всё равно невозможно.

Мы делаем такой API, чтобы его вообще нельзя было неправильно использовать. Так как очень большие риски для нас, в том числе и денежные.

C>>Или это могут быть не пользователи вообще, а другие чувствительные к безопасности объекты.

S>У всех чувствительных к безопасности объектов работают права доступа. Это и есть основной способ защиты от злоупотреблений. Сценарий конфликта идентификаторов приводит в REST к "кто последний, того и тапки", поэтому хитровывернутые пользователи, предсказывающие идентификаторы, просто теряют "свои" объекты.
Ну вот как быть в случае с "заранее создали пользователя"?

Кстати, это может быть и другой объект. К примеру, создали документ первым запросом, а потом в него загрузили секретное содержимое. С правами доступа тоже всё ОК — пользователь-враг сам создал документ и имеет к нему полный доступ. Админ тоже имеет полный доступ, так как он админ.
Sapienti sat!
Re[20]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 08:18
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Выдавить-то не проблема, но для этого этот набор надо сначала знать.

Ну вот я вам рассказываю
D>Упс, первый раз слышу. Кто и зачем этого может пожелать? (Смутно помню стародавние срачи про производительность индексов, но мне это всё казалось слишком далёким от реальной жизни простых смертных.)
В среднем раз в 3 месяца на нашем форуме, и 1 раз в месяц на sql.ru поднимается этот вопрос — очередной нуб удивляется, что rollback транзакции с insert приводит к появлению дырки в identity.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 08:19
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Я дописываю версию (а точнее, mtime и/или filesize и/или md5 — в зависимости от языка) в Query String.

Для ресурсов-из-сборок в ASP.NET делается точно так же.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 08:24
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Ctrl+F5 рулит, гыгы.

Не, в случае 302 даже Shift-Ctrl-F5, а также перезагрузка машины никак не помогают.

D>Ещё можно сделать всё на ажаксе, а в корень прогружать пустую bootstrap-страницу.

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

D>А вообщеЮ в HTTP кеширование несколько противоестественное, потому что решение принимает клиент, который может вообще игнорировать заголовки сервера

Кэширование в HTTP на удивление хорошее (с учётом даты разработки).

D>причём в обе стороны: Ctrl+F5 чтобы всегда грузить, или вон system.console со своей Оперой (на редкость беспредельничающий браузер, и был таковым с самого начала: "ускорение загрузки" за счёт наплевательского отношения к протоколу).

Это, по большому счёту, проблемы клиента. Сила кэширования HTTP — в прозрачности. То есть я могу поставить между клиентом и сервером squid, или nginx, или lightthpd, и получить performance boost "на ровном месте" без вложений в инфраструктуру на клиенте или на сервере. Для произвольного RPC мне придётся во-первых писать умного прокси с нуля, во-вторых придётся долго ловить в нём глюки.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 08:31
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Так и где здесь REST? Вижу обычный RPC.
Там же, где и всегда. В отличие от RPC, транзакции идемпотентны, поэтому в случае сбоя я могу спокойно выполнять повторный PUT, не боясь второго перевода.

C>SOAP был бы проще, уже почти жалеем, что не выбрали его. Заодно меньше проблем с валидацией схемы данных с ним.

Оппа, недописал — есть JavaScript библиотеки с поддержкой WS-ReliableMessaging?


C>Клиент — на JS.

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

C>Не веришь, что бывают уязвимые GUID'ы? Вот пожалуйста, почитай тред на SO: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript — ВСЕ примеры оттуда уязвимы чуть менее, чем полностью (Math.random() — криптографически небезопасен).

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

C>Мы делаем такой API, чтобы его вообще нельзя было неправильно использовать. Так как очень большие риски для нас, в том числе и денежные.

1. Такого API не бывает.
2. Возможности правильно/неправильно использовать не зависят от выбора между REST и RPC.

C>Ну вот как быть в случае с "заранее создали пользователя"?

Я же написал ниже.

C>Кстати, это может быть и другой объект. К примеру, создали документ первым запросом, а потом в него загрузили секретное содержимое. С правами доступа тоже всё ОК — пользователь-враг сам создал документ и имеет к нему полный доступ. Админ тоже имеет полный доступ, так как он админ.

При публикации (тем более в первый раз) секретного содержимого нужно обнулять права доступа к документу. Это сходу решает все ваши несуществующие проблемы угона ID.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 10.02.14 08:48
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Так и где здесь REST? Вижу обычный RPC.

S>Там же, где и всегда. В отличие от RPC, транзакции идемпотентны, поэтому в случае сбоя я могу спокойно выполнять повторный PUT, не боясь второго перевода.
Так нету буквы R — Representational. Обычный RPC есть.

C>>SOAP был бы проще, уже почти жалеем, что не выбрали его. Заодно меньше проблем с валидацией схемы данных с ним.

S>Оппа, недописал — есть JavaScript библиотеки с поддержкой WS-ReliableMessaging?
Оно руками реализуется в несколько строк (на клиенте).

C>>Клиент — на JS.

S>Тогда вообще проблемы нет. Пишете клиента сами, и избегаете шансов нарваться на идиода.
У нас модель такая — на нашей платформе пишутся приложения, мы приложениям даём API.

C>>Не веришь, что бывают уязвимые GUID'ы? Вот пожалуйста, почитай тред на SO: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript — ВСЕ примеры оттуда уязвимы чуть менее, чем полностью (Math.random() — криптографически небезопасен).

S>Вы сами читали по ссылке? Во-первых, там есть пример с криптостойким генератором. Во-вторых, между "криптографически небезопасен" и "уязвим" — пропасть. Пример с подмешиванием таймстэмпа делает предсказание идентификатора нереализуемым.
Читал. Извиняюсь, что не заметил пример с криптостойким ID — он потерялся на фоне уязвимых примеров.

Math.random() угадывается из соседней вкладки браузера, например. И подмешивание timestamp'а не решает ничего, так как идентификаторов можно насоздавать заранее тонну.

C>>Мы делаем такой API, чтобы его вообще нельзя было неправильно использовать. Так как очень большие риски для нас, в том числе и денежные.

S>1. Такого API не бывает.
S>2. Возможности правильно/неправильно использовать не зависят от выбора между REST и RPC.
У Amazon'а примерно такой API есть — его неправильно использовать просто нельзя.

C>>Кстати, это может быть и другой объект. К примеру, создали документ первым запросом, а потом в него загрузили секретное содержимое. С правами доступа тоже всё ОК — пользователь-враг сам создал документ и имеет к нему полный доступ. Админ тоже имеет полный доступ, так как он админ.

S>При публикации (тем более в первый раз) секретного содержимого нужно обнулять права доступа к документу. Это сходу решает все ваши несуществующие проблемы угона ID.
Такими темпами сброс прав надо на каждую операцию будет делать.
Sapienti sat!
Re[17]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sharov Россия  
Дата: 10.02.14 08:59
Оценка:
Здравствуйте, Jack128, Вы писали:


J>А зачем предсказывать?? ставишь снифер клиенту1 и видишь, что тот обращается по урлу www.example.com/api/users/F889A953B7C543AB82762A2E02E299BF вот те гуид и есть. Другое дело, что если "клиент 2 (непривилегированный)" может обресетить пароль, то это вообще какая та странная безопасность. И никакими тикитами с сервера тут не защитится.


А https не спасет от этого? Я понимаю, что урлу можно поглядеть, а если гуид
передавать в заголовке запроса( ну в каком-нибудь там...)?
Кодом людям нужно помогать!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.