Как стать автором
Обновить

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

…и сайт больше не статический…

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

И заставить пользователей в ужасе разбежаться

Ужас-то в чём?

У вас в описании этого схематоза слово "ключ" употребляется 6 раз в 4 значениях. Этого достаточно.

Это в каких таких 4 значениях?

Секретный, общий, публичный, приватный

Для "простого пользователя" (tm) уже ничего непонятно и сложно

Значение одно и то же. Это разные типы ключей.

А простой пользователь видит обычную форму входа. Ему тут зачем про ключи вообще знать?

Интересный подход. А что он даёт по сравнению с генерацией ключа из пароля и обычным симметричным шифрованием через AES?

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

Во, запилил демку с упрощённой схемой без приватных ключей:

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

Или вместо этого выдать каждому пользователя клиентский X.509 сертификат - и пускай с ним в статический сайт ходят.

Так ок, у нас есть DEK (симметричный), есть KEK (симметричный) по KDF, мы зашифровали клиентский приватный ключ (асимметричный) с помощью KEK (симметричный) по PBKDF2 (пароль знает только пользователь) допустим... Но что с нашим приватным ключом (асимметричный)? Он так же в открытую лежит на статическом хостинге? Или он тоже зашифрован, но данные расшифровки лежат рядом?

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

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

и.. выложить всё это дело на статический хостинг

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

Сенсация! Пользователь, получивший доступ к контенту, может его скопировать и выложить куда угодно не раскрывая свою анонимность! Срочно на главную! Страна опасносте!

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

Вообще у Pinata была штука которая вроде бы так работала (в сочетании с IPFS и как то (по их словам) обеспечивали безопасность, в условиях когда вообще хостингом непонятно что теперь нет - https://knowledge.pinata.cloud/en/articles/8313206-sunsetting-submarine-private-files-and-private-api-faqs и сами предлагают как замену - https://www.litprotocol.com/

Там смарт-контракты по полной программе, клиенту нужен кошелек и так далее. И мне вот не вполне понятно из описания LitProtocol на https://developer.litprotocol.com/v3/resources/how-it-works - насколько оно корректно работает то.

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

Вот!

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

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

Чувуак, спасибо тебе, пригодилось)

Осталось научиться угонять аккаунты через эту замечательную форму ?

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

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

Вообще ещё сто лет назад делал раздачу статики nginx только авторизованным пользователям и я не про basic auth, для которого вообще ничего не надо, а именно со сложной авторизацией через бек. Это можно сделать через редиректы на внутренние именованные location nginx для пользователей которым доступ разрешен. Можно нагуглить конкретику. Nginx всё же раздаёт статику эффективнее чем бек на Python

Хм, спасибо

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

Да нет, не должна. Просто решение нужно выбирать в зависимости от задачи.

Я хотел дать доступ к сайту ограниченному кругу людей — и поскольку у каждого из них есть Телеграм, это можно было использовать.

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

  • пользователь сам находит бота, нажимает Start

  • бот пишет сообщение: ваша ссылка для входа https://example.com/login/random-token

  • сайт ставит этот токен в куку, и тем самым разрешает доступ. Тут и кода меньше писать, и пользователю меньше делать непонятных телодвижений.

Да, нормальный способ. Я использовал похожую схему в другом проекте.

Но на самом деле Telegram Auth Widget заставляет делать телодвижения (ввод номера телефона и подтверждение входа) только во время первой аутентификации. Если пользователь уже входил на другой сайт, например, то ему останется только нажать на кнопку.

Для подобных задач использую https://github.com/oauth2-proxy/oauth2-proxy

телеги в провайдерах у них нет, можно написать своего провайдера

т.е. для доступа к чему-либо (статике или сайту, неважно) вначале надо авторизоваться через oauth2

Немного пиара. Я создал для таких целей https://github.com/Jipok/Jauth

Значительно проще в установке чем oauth2-proxy. Сразу Let's Encrypt из коробки.

И есть уникальная возможность в виде логина через ssh. Учитывая что у всех разрабов ключи уже есть, такой способ очень удобный. А для обычных пользователей есть вариант входа через telegram.

Я сейчас через него проксирую 18 сервисов на своём домашнем сервере.

Класс
А есть возможность выбора? Типа войти через гугл или яндекс или телеграмм

Только ssh и/или телеграм. И тот и другой можно отключить(точнее не включать).

Гугл и яндекс мне идеологически противны. Изначально я думал сделать вход через github, но потом понял что привязка к такому сервису(а его как раз майкрософт хотели купить) не есть хорошо. Ну и додумался до ssh, ибо если есть гитхаб, то ключевая пара тем более есть. Поддержка телеграма появилась только через пару лет. Планов на какой-либо oauth2 привязанный к большой корпорации нет.

Яндекс - потому что сейчас корп почта через admin.yandex.ru у многих туда привязана. Гугл тоже самое.
Т.е. условно разрешаешь вход на какие-то корп сайты через свой домен *@example.com который привязан к гуглу, или через. *@example2.ru который привязан к яндексу.

Ну в принципе можно добавить вход через почту. Без пароля. Т.е. добавить поле ввода под email. И Jauth будет через указанный в настройках smtp отправлять письмо с одноразовой ссылкой по которой можно войти. Норм?

Ключи в let's encrypt получаются через web? по DNS + например cloudflare API - возможности в принципе не планируется?

SSL НЕ через letsencrypt и НЕ self-signed а допустим серверу этому выданы ключи Subordinate CA моего (подписанного конечно же моим Root CA которому доверяют все устройства с которых кто надо может зайти) (разумеется сервер должен отдавать всю цепочку)

Ключи в let's encrypt получаются через web?

Используется встроенный в go пакет autocert. Он реализует HTTP-01 challenge, т.е. через web.

по DNS + например cloudflare API - возможности в принципе не планируется?

Честно говоря, до вашего вопроса я даже не знал про такую штуку. Ну знал что для wildcard что-то там с dns надо мутить. Сейчас нагуглил go-acme/lego. Так что в принципе можно будет на него перейти. Но не в ближайшее время.

SSL НЕ через letsencrypt и НЕ self-signed а допустим серверу этому
выданы ключи Subordinate CA моего (подписанного конечно же моим Root CA
которому доверяют все устройства с которых кто надо может зайти)
(разумеется сервер должен отдавать всю цепочку)

Я таким никогда не заморачивался, но для сервера по сути нет разницы self-signed это или цепочка. Если у вас несколько *.crt файлов, то вы их просто соединяете в один и отдаёте его Jauth вместе с ключом. Такая опция уже есть:

[Certificate]
# Type can be:
# autocert — use Let's Encrypt
# self‑signed — autogenerate
# manual — specify certificate. Example:
Type = “manual” # Default self‑signed
Cert = “some‑cert.crt” # Default “self‑signed.crt”
Key = “some‑cert.key” # Default “self‑signed.key”

Ты на ctf2 заходи, хоть иногда, но заходи...

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

>В куки я храню id пользователя в Телеграме, зашифрованное через JWT.

JWT не шифрует, а только энкодит. Нельзя хранить чувствительные данные в JWT!

https://jwt.io/#debugger-io вот тут можно все "расшифровать" обратно

Ну оговорился автор, бывает. Всё равно этот id нет смысла прятать от пользователя, а кроме него и сервера больше никто этот id и не прочитает.

К сожалению, совершенно непонятно, как быть в случае отзыва токена (logout из Telegram в браузере). Данные, полученные при авторизации, всё равно же остаются валидными. Вопрос, конечно, не к автору статьи, а к разработчикам Telegram.

Сделать отдельный logout на сайте, и возложить на пользователя ответственность разлогиниться везде, если ему надо зачистить сессии.

Наверное, я неправильно выразился. К примеру, пользователь вообще удалил свой аккаунт из Telegram. В документации не указан никакой endpoint, чтобы сделать запрос и проверить корректность данных on demand, так сказать. Либо объясните мне, как правильно делать в таком случае. На всякий случай, цитирую документацию:

To prevent the use of outdated data, you can additionally check the auth_date field, which contains a Unix timestamp when the authentication was received. (https://core.telegram.org/widgets/login)

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

Спасибо, годный материал!
Раз уж заговорили про ТГ, может кто подскажет, как настроить отслеживание сообщений в телегу? То есть задача такая: на сайт гоним трафик с сео, контекста и cpa сетей. Обращения в основном все сыпятся в телегу и воцап. Нужно выстроить аналитику, чтобы считать лиды, и видеть с какого источника сколько приходят. Стандартное решение - настроить цель в Яндекс Метрике, чтобы считала клик на значок телеги и воцапа на сайте. Но эти целевые действия не равны реальным клиентам. То есть нужно, чтобы передавалась статистика по лидам, когда пользователь написал в мессенджер, и чтобы передавалась в CRM utm-прометка, чтобы понимать с какого источника пришел лид. Был у кого-нибудь опыт такого настройки такой аналитики? Может сервис готовый есть для этого?

Слишком сложно для 3х человек. HTTP BASIC AUTH для такой задачи выше крыши.

Хотя если вы на ЗП сидите и делать нечего, то можно.

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

Это правда. Просто в моём случае действительно только статика, и код с call_next в начале получается чуть более лаконичным.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории