уязвимости postmessage и $.post()

todd

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

Еще одна догадка возникла по поводу аджакс постов $.post(). Он отправляет на сервер пост запрос с просьбой авторизировать пользователя и проверить его данные. Если все впорядке, возвращает переменную data, в которой хранится логин авторизованного пользователя.

Весь остальной код пока использует только эту переменную для автоматической авторизации и установки прав пользователя.

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


Может кто нибудь знает принципы защиты этих дыр?

Исходник, думаю, тут не нужен, т.к. прошу просто рассказать о принципах или кинуть ссылку. Но если понадобится - напишу аналогию
 

Фанат

oncle terrible
Команда форума
Но догадываюсь, что postmessage очень уязвим, т.к. посредством него можно передать все что угодно.
Что именно?
любой желающий может изменить ее через адресную строку
о сессиях слышал когда-нибудь?
 

todd

Новичок
Фанат
Конечно же слышал. Не нравится мне этот гонор на форумах.
Просто сессии итак используются - сервер вытаскивает логин пользователя из сессии и отправляет его клиенту в js. а далее все проверки происходят у клиента в браузере.
Я не знаю, есть ли возможность синхронизировать серверную сессию с клиентским javascript'ом.

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

todd

Новичок
С сессиями всё решилось, нашёл плагин jQuery.session plugin
а вот пост мессадж может подвести. он передает данные другим доменам, т.к. данные эти - джаваскрипт, ими могут воспользоваться
 

todd

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

Фанат

oncle terrible
Команда форума
ну, например показ информации
Информацию показывает сервер, а не клиент. Если твой сервер проверяет аутентичность клиента по имени, а не по идентификатору сессии, то это проблема у сервера. И связана она с кривизной рук разработчика, а не с уязвимостями postmessage и $.post()
А дальше этот скрипт сработает на моем сервере.
С какой стати он отработает, если его никто не ждет?
 

todd

Новичок
Фанат
С руками разработчика всё в порядке.
Положение вещей таково, что сессии - не идеальный выход. Я ведь уже сказал, что постмессаги отправляются с других доменов. Как по твоему они будут читать сессии с моего сервера?
С какой стати он отработает, если его никто не ждет?
Омг. Откуда тебе знать, что его никто не ждёт? если в коде прописано, что на сервер должно что то передаваться, значит это что то там ждут.

Я не прошу охарактеризовать руки разработчика, а прошу помочь с идеей защиты кода.
 

todd

Новичок
Опишу подробнее, что происходит:
на сервере есть некий код, который могут встраивать к себе другие сайты. (API приложение). Встраивается он посредством iframe (непосредственную передачу переменных использовать не могу по некоторым причинам, по тем же причинам не подходят распространенные библиотеки для создания API приложений)

Итак, сторонний сайт встроил приложение к себе на страницу. Теперь он должен передать данные внутрь iframe. Это происходит посредством PostMessage(). Ты должен понимать, что данные еще никоим образом не коснулись моего сервера, они по прежнему находятся в браузере клиента, просто теперь пробрались сквозь мембрану iframe.

Далее - внутри iframe есть код, который слушает входящие сообщения, и, как только сообщение пришло - отправляет его на мой сервер. Мой сервер обрабатывает эти данные, сверяет и отправляет новые, сгенерированные внутрь iframe. Далее iframe при помощи PostMessage() отправляет их на тот сторонний сайт. И... Клиент мгновенно получает данные с моего сервера.

Несложно увидеть ряд брешей в коде. но как залатать их я действительно не знаю.
Именно это мне и нужно
 

hell0w0rd

Продвинутый новичок
todd
А какая разница как до сервера доходят данные? Я могу сесть и curlом тебе слать запросы. Сервер не должен ничего знать о том как ему запросы поступают. Вообще плевать. Он также не знает ajax это запрос или нет - он видит, что есть заголовок и как-то на него реагирует.
Поэтому на сервере данные должны проходить валидацию, вне зависимости от того, прошли ли эти данные валидацию на стороне клиента, или нет.
И еще - по поводу всей этой свистопляски с iframe - зачем? Почему нельзя написать просто библиотеку? Я бы не стал на сайт просто так iframe встраивать
 

todd

Новичок
GusakovNick
Я подразумеваю немного другую дырку - те данные, которые в итоге поступают на сторонний сайт. Как быть с ними? Ведь они передаются посредством js. Допустим на него пришел логин пользователя var login, затем переслался на сервер стороннего сайта. И html код сгенерировался, в соответствии с логином.

Но злоумышленник просто может прописать: js: login='admin'. И зайти в админ панель стороннего сайта.
Я, возможно, что то упускаю, конечно
 

hell0w0rd

Продвинутый новичок
GusakovNick
Я подразумеваю немного другую дырку - те данные, которые в итоге поступают на сторонний сайт. Как быть с ними? Ведь они передаются посредством js. Допустим на него пришел логин пользователя var login, затем переслался на сервер стороннего сайта. И html код сгенерировался, в соответствии с логином.

Но злоумышленник просто может прописать: js: login='admin'. И зайти в админ панель стороннего сайта.
Я, возможно, что то упускаю, конечно
Не очень понял. Что там будет? авторизация?
 

todd

Новичок
Забыл сказать, что проверка на сторонних сайтах может даже проводиться через js, т.к. их сервера могут не поддерживать php. ucoz допустим.
В теории - предполагаю выход в переменной js, к которой не будет доуступа из адресной строки.
Или, может быть, шифрование, вроде md5 (без возможности расшифровки) средствами js
 

hell0w0rd

Продвинутый новичок
GusakovNick
Да, авторизация и регистрация
Такие вещи должны делаться через сессию. Сайты которые будут юзать это дело могут работать только с сессией и отсылать запросы вам на сервер ее + запрос, а в ответ вы можете предоставить логин или что-то там еще. Только не думаю что ucoz позволяет просто так встраивать iframы.
Учтите сессия - имеется ввиду не реальная сессия юзера, а сессия конкретно для этого приложения.
 

todd

Новичок
GusakovNick
Учтите сессия - имеется ввиду не реальная сессия юзера, а сессия конкретно для этого приложения.
Простите за шквал вопросов ) Но я никогда раньше не слышал об этом. Как это реализуется? или где можно об этом почитать?
 

hell0w0rd

Продвинутый новичок
GusakovNick

Простите за шквал вопросов ) Но я никогда раньше не слышал об этом. Как это реализуется? или где можно об этом почитать?
Я не могу с уверенностью сказать что делать надо именно так - я никогда этого не делал.
Но если делать именно так - то как обычный механизм сессий. При запросе данных ресурсом проверяете есть ли у вас для этого сайта доступ к этому юзеру или нет. Как уж вы ее организуете - ваш выбор.
 

fixxxer

К.О.
Партнер клуба
Например так.

Каждому приложению выдается пара id и secret. secret держится, очевидно, в секрете, о нем знает только api и приложение.

Далее 2 варианта (хотя на самом деле больше =).

1. подпись всех запросов (сессия внезапно не нужна вообще). все запросы подписываются через добавляемый к запросу параметр sig = hash( запрос + IP-адрес + secret ), где hash - хэш функция (sha256, например), запрос - однозначно сериализованный набор остальных параметров (например, ksort -> http_build_query). В запросах также передается id в открытом виде. Сервер по id знает secret и может проверить правильность подписи.

2. digest auth с сессией:

0) все те же id и secret на месте
1) клиент стучится на сервер
2) сервер дает ему совершенно случайную строку rnd и запоминает, что такое сюда выдавал
3) клиент отвечает по схеме из п.1, только теперь запрос = ( id, rnd )
4) сервер проверяет подписанный ответ и выдает session id на комбинацию (id, ip address)
5) дальше клиент во всех запросах передает id и session_id
6) сессия экспайрится по таймауту
 

todd

Новичок
Переварил всё ) Способ очень интересный, но в этом случае разработчикам других сайтов придется делать такую проверку каждый раз, когда они попытаются достать данные с моего сервера. Хочется облегчить им труд.

У меня появилась одна мысль:
что если написать так?

PHP:
function getmessage (login){
     Storage.put("login", login);
}
window.addEventListener("message", getmessage,false);
Злоумышленник сможет влезть внутрь функции getmessage и изменить локальную переменную login каким нибудь образом?
 
Сверху