Такое решение бессмысленно. Как «работает» xss токен:
— токен лежит в сессии (зашифрованный в куках или редисе, например);
— вы отдаете его только пользователю с этой сессией (это ключевой момент);
— при запросах от этого пользователя вы проверяете, совпадает ли токен из запроса с токеном из сессии.
В вашей реализации токен для всех один. Злоумышленнику нужно его 1 раз узнать, и он может его использовать, пока вы конфиг не поменяете, размещая на своих сайтах формы. Реферер-то вы просто проверяете на совпадение с текстом в токене (читай: сейчас у вас токен ничего не защищает).
Для чего нужен токен: чтобы от имени пользователя не слали запросы с других сайтов. Например, на сайте злоумышленника кнопка «скачать без смс и регистрации» отправляет аяксом POST http://your-domain/admin/destroy_all (ну или просто создания спам-поста от имени пользователя).
Если же вы уберете проверку токена для входа, то всё, что сможет сделать злоумышленник — залогинить пользователя. По-моему, это не страшно.
Если нужно запретить логин со сторонних сайтов, то нужно
— либо часто обновлять токен и подписывать его. Для этого на всех сайтах надо логику подписи делать, это не сложно, но без нее никак.
— либо просто использовать белый список рефереров.
> Но это совсем не решения, т.к. открывают дыру в безопасности сайта.
А какая дыра открывается, если отключить проверку токена для sessions#create? Я не могу с ходу придумать, почему этого делать нельзя. Для большей уверенности можно просто добавить проверку реферера.
> не получится обратиться к "/user/1/posts", "/user/1/posts.old_api", "/user/1/posts.new_api2"
Если так делать, в контролере придется хранить код на 3+ реализации апи. А это, рано или поздно — конфликты имен и функционала. По-моему, если решили делать новую версию апи, то лучше сразу в отдельный нэймспэйс вынести, а старый код оставить как есть. А если проект с нуля, то такой подход, просто избавит от этих проблем в будущем.
Мы только используем namespace: :site вместо scope module: :web. Так урл-хэлперы будут с префиксами, и вызовы их яснее: можно ошибиться и написать в админке form_for user / link_to user / user_path вместо form_for [:admin, user] / link_to [:admin, user] / admin_user_path. Вариант с нэймспэйсом просто выдаст ошибку, а со скоупом — вернёт неверный урл. Вроде бы был ещё какой-то тонкий момент связанный с этим, но сейчас не вспомнил.
Зачем так усложняете? Вы видели реализацию .constantize? :) Это метод для стадии инициализации, его не надо в рантайме использовать везде. const_get в большинстве случаях подойдет всем. Но тут я уверен, что model.class должно хватить (или model.model.class для презентеров).
Мы еще делали show_attributes resource, :attr1, attr2,…
def ицит
твоего присутствия
Всё острее день ото дня.
Я скучать по тебе начинаю
Кофе с утра заваривая.
Больше не в силах терпеть я!
Пусть это знают все:
'Тебя я люблю до безумия!'
P.S. Больше чем кодить back end
Про конкатенацию строк.
Я с растом мало имел дел, тонкостей могу не знать. Поискал, предлагают конкатенацию делать через интерполяцию с макро format!.. Это не то?
Просто последнее время все больше таких статей попадалось, и как по мне так это просто нытье. Возможно, они кому-то и были полезны, но мне такие статьи кажется вредными. Я бы не стал делиться такими :) Остальной материал — классный!
Если по существу: смешно стало, когда дошел до момента, когда он «неожиданно узнал, что try это тоже из AS». Странно, что даже в комментариях никто не вспомнил про each_with_object, который добавили в язык, хотя изначально это был тоже манкипатч из AS. Идея с pluck, мне тоже сначала не очень понравилась, наверное, я так и продолжу писать map. Но почему бы не попробовать — многие штуки в рельсах не приживались, и их выпиливали через какое-то время.
Спасибо, очень интересно! Скажите, вы сами разделяете точку зрения статей «Cutting Corners or Why Rails May Kill Ruby», «Ruby is defined by terrible tools»?
Это да. Я в другой ветке писал, что язык за гибкость язык винить — странно, если эта гибкость полезна. А в руби я не могу сейчас вспомнить что-то бесполезное. Дело в людях: кто-то не умеет пользоваться, кто-то пользует фичу не по назначению.
Я, все-таки, считаю, что лучше поднимать уровень понимания в команде. Ведь это довольно базовые вещи: 1 раз понял — пользуешься всегда. К тому же, код написанный не в команде тоже иногда (а может и часто) надо будет читать (фрэймворки/библиотеки). И он не всегда написан хорошо.
Ставку делали на удобство и гибкость. Всеми фичами можно и нужно пользоваться. Только не все могут нормально, поэтому и возникают потом проблемы в поддержке написанного.
> self.included — это чёрная магия, за которую в production коде надо бить по рукам, она нужна для гемов, но никак не для обычного кода
ActiveSupport::Concern вы не используете?
> class << self — это хипстеры используют для своих мини проектов, так писать не нужно вообще
Потом методы класса можно по файлу в неожиданных местах находить. attr_accessor через singleton_class.send пишите, или для него можно побыть хипстером?
pry в помощь. Лучше посмотреть, какие классы в геме есть, перед тем как ставить, чтобы знать где могут быть проблемы (http://rightscale.rubyforge.org/right_http_gem_doc/ вверху есть Net::HTTP). тем более в случае с таким плохо документированным гемом.
А так от манкипатчинга только польза: можно поправить за кем-то ошибки или сделать бэкпорт фичи без форка. Проблемы из-за людей :)
— токен лежит в сессии (зашифрованный в куках или редисе, например);
— вы отдаете его только пользователю с этой сессией (это ключевой момент);
— при запросах от этого пользователя вы проверяете, совпадает ли токен из запроса с токеном из сессии.
В вашей реализации токен для всех один. Злоумышленнику нужно его 1 раз узнать, и он может его использовать, пока вы конфиг не поменяете, размещая на своих сайтах формы. Реферер-то вы просто проверяете на совпадение с текстом в токене (читай: сейчас у вас токен ничего не защищает).
Для чего нужен токен: чтобы от имени пользователя не слали запросы с других сайтов. Например, на сайте злоумышленника кнопка «скачать без смс и регистрации» отправляет аяксом
POST http://your-domain/admin/destroy_all(ну или просто создания спам-поста от имени пользователя).Если же вы уберете проверку токена для входа, то всё, что сможет сделать злоумышленник — залогинить пользователя. По-моему, это не страшно.
Если нужно запретить логин со сторонних сайтов, то нужно
— либо часто обновлять токен и подписывать его. Для этого на всех сайтах надо логику подписи делать, это не сложно, но без нее никак.
— либо просто использовать белый список рефереров.
А какая дыра открывается, если отключить проверку токена для sessions#create? Я не могу с ходу придумать, почему этого делать нельзя. Для большей уверенности можно просто добавить проверку реферера.
Если так делать, в контролере придется хранить код на 3+ реализации апи. А это, рано или поздно — конфликты имен и функционала. По-моему, если решили делать новую версию апи, то лучше сразу в отдельный нэймспэйс вынести, а старый код оставить как есть. А если проект с нуля, то такой подход, просто избавит от этих проблем в будущем.
Мы только используем
namespace: :siteвместоscope module: :web. Так урл-хэлперы будут с префиксами, и вызовы их яснее: можно ошибиться и написать в админкеform_for user / link_to user / user_pathвместоform_for [:admin, user] / link_to [:admin, user] / admin_user_path. Вариант с нэймспэйсом просто выдаст ошибку, а со скоупом — вернёт неверный урл. Вроде бы был ещё какой-то тонкий момент связанный с этим, но сейчас не вспомнил.(рукалицо)
Зачем так усложняете? Вы видели реализацию .constantize? :) Это метод для стадии инициализации, его не надо в рантайме использовать везде. const_get в большинстве случаях подойдет всем. Но тут я уверен, что model.class должно хватить (или model.model.class для презентеров).
Мы еще делали show_attributes resource, :attr1, attr2,…
foo(format!("Hello, {}", "world!"));Я с растом мало имел дел, тонкостей могу не знать. Поискал, предлагают конкатенацию делать через интерполяцию с макро format!.. Это не то?
Если по существу: смешно стало, когда дошел до момента, когда он «неожиданно узнал, что try это тоже из AS». Странно, что даже в комментариях никто не вспомнил про each_with_object, который добавили в язык, хотя изначально это был тоже манкипатч из AS. Идея с pluck, мне тоже сначала не очень понравилась, наверное, я так и продолжу писать map. Но почему бы не попробовать — многие штуки в рельсах не приживались, и их выпиливали через какое-то время.
Возможно все
Я, все-таки, считаю, что лучше поднимать уровень понимания в команде. Ведь это довольно базовые вещи: 1 раз понял — пользуешься всегда. К тому же, код написанный не в команде тоже иногда (а может и часто) надо будет читать (фрэймворки/библиотеки). И он не всегда написан хорошо.
ActiveSupport::Concern вы не используете?
> class << self — это хипстеры используют для своих мини проектов, так писать не нужно вообще
Потом методы класса можно по файлу в неожиданных местах находить. attr_accessor через singleton_class.send пишите, или для него можно побыть хипстером?
А так от манкипатчинга только польза: можно поправить за кем-то ошибки или сделать бэкпорт фичи без форка. Проблемы из-за людей :)