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

hell0w0rd

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

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

PHP:
function getmessage (login){
     Storage.put("login", login);
}
window.addEventListener("message", getmessage,false);
Злоумышленник сможет влезть внутрь функции getmessage и изменить локальную переменную login каким нибудь образом?
да, сможет. То что ты хочешь сделать - называется открытое API. Чтобы сделать его приятным - посмотри на уже существующие:
http://vk.com/page-1_2369497
http://api.yandex.ru/yaru/doc/ref/concepts/yaru-api-intro.xml
http://habrahabr.ru/post/38730/
ну и тд
 

todd

Новичок
GusakovNick
PHP:
function getmessage (login){
     Storage.put("login", login.data);
}
window.addEventListener("message", getmessage,false);
Код был написан не совсем верно. Скорее всего вопрос глупый, но все таки хочу удостовериться. А так?

То что ты хочешь сделать - называется открытое API. Чтобы сделать его приятным - посмотри на уже существующие:
Ок, посмотрел. +Попытался найти что нибудь по запросу Открытое API ничего, что помогло бы на данном этапе пока не нашел
 

todd

Новичок
Проверил всё, попытался хакнуть через адресную строку, но ничего не вышло. Я, конечно не знаю всех методов, но, вроде как, доступа к login.data у злоумышленника нет
 

WMix

герр M:)ller
Партнер клуба
todd
дело не в js, браузер с сервером общается на http протоколе, к примеру в телнете можно так написать
Код:
$ telnet phpclub.ru 80
Trying 176.9.111.107...
Connected to phpclub.ru.
Escape character is '^]'.
GET /talk/threads/%D1%83%D1%8F%D0%B7%D0%B2%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8-postmessage-%D0%B8-post.75593/page-2 HTTP/1.1
Host: phpclub.ru

HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Fri, 12 Apr 2013 17:59:10 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.4.13
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-control: private, max-age=0
Set-Cookie: xf_session=6d2bbdfc5bce512ad6ab9d397bdfb863; path=/; httponly
Last-Modified: Fri, 12 Apr 2013 17:59:10 GMT
Content-Length: 45089

<!DOCTYPE html>
<html id="XenForo" lang="ru-RU" class="Public LoggedOut" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>

	<meta charset="utf-8" />
	<base href="http://phpclub.ru/talk/" />
	
	<title>уязвимости postmessage и $.post() | Страница 2 | PHPClub - клуб разработчиков PHP</title>
....
таким образом я подделаю любую переменную
 

fixxxer

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

Если хочется авторизовывать без сервер-сервер кода, выдавай api key на домен.
Посмотри как это сделано у других, например, на яндекс-картах.
 

todd

Новичок
fixxxer
Клиентская часть:

PHP:
<iframe id="iframe" onload="post('message');"></iframe>
<script>
function post(data){
        var win = document.getElementById('iframe').contentWindow;
        win.postMessage(data,'*');
}
function listener(server){
     if (тут проверка, пришло ли что то похожее на ключ){
          server.source.postMessage(server.data, '*');
     }elseif(тут проверка, есть ли что то похожее на логин, ну например){
          document.cookie = 'login = server.data';
     }
}
if (window.addEventListener){
	window.addEventListener("message", listener,false);
} else {
	window.attachEvent("onmessage", listener);
}
</script>
Серверная часть:

PHP:
<?$key = ...generate key...; $login = 'login'?>
<script>
function listener(mes){    
    if (mes.data == 'message'){
          mes.source.postMessage('<?=$key?>', '*');
    }
    if (mes.data == '<?=$key?>'){
          mes.source.postMessage('<?=$login?>', '*');
    }
}
if (window.addEventListener){
	window.addEventListener("message", listener,false);
} else {
	window.attachEvent("onmessage", listener);
}
</script>
Написал на скорую руку, не протестил. может где что недодумал. Но суть, вроде ясна - тоесть такой код с отправкой и проверкой ключа не получится взломать?
 

hell0w0rd

Продвинутый новичок
todd
Iframe - не нужен. Через него только видео что и хорошо встраивать, и то побыстрее бы умер этот способ.
http://touchdev.ru/documents/3037 - вот почитай про то как можно сделать авторизацию c API вк. Или погугли еще инфу по этой теме.
Хотя мне кажется тебе нужно то что описано под заголовком Способ рекомендуемый
 

todd

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

Ну а что насчет кода наверху? :)

Безопасный? Или я снова что то упустил?
 

hell0w0rd

Продвинутый новичок
GusakovNick
Просто iframe в моем случае - идеальное решение интерактивности, простоты обработки входных данных (есть лишь один канал, через который могут передаваться сообщения, поставить на него фильтр довольно просто, С Ифреймами знаком каждый начинающий веб разработчик. И он легко разберется с тем, что именно ифрейм вставляет плагин на его сайт, без чтения лишней документации. Самый большой минус апи библиотек, которые видел я - отсутствие возможности интерактивного общения в реальном времени клиента с сервером. Вконтакте, фейсбук обходят это маской реального времени - просто открывают страницу подтверждения входа. Но это очень мозолит глаза. Только ифрейм может позволить создавать прозрачные, легко интегрируемые интерактивные приложения, на мой взгляд.
Ага, только любой не начинающий разработчик не согласится просто так юзать ифрейм. Вы сегодня предоставляете авторизацию, а завтра там будет реклама. Вы еще хотите чтобы разработчики из вашего iframe тащили данные. Я не знаю кому такое нужно. Если хотите чтобы работа с вашим АПИ была удобной - напишите библиотеку.
 

todd

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

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

hell0w0rd

Продвинутый новичок
Вконтакте, кстати, тоже предоставляет возможность встривания своих апи посредством ифреймов ) Не знаю, как остальные сайты, конечно.

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

todd

Новичок
Ну принцип того, как я буду это реализовывать то понятен )
Видно, как передается, возвращается и сверяется ключ.
Ну, разве что, все условия и вывод на сервере переведу из js на php, для безопасности
 

todd

Новичок
PHP:
<iframe id="iframe" onload="post('message');"></iframe>
<script>
function post(data){
        var win = document.getElementById('iframe').contentWindow;
        win.postMessage(data,'*');
}
function listener(server){
     if (тут проверка, пришло ли что то похожее на ключ){
          server.source.postMessage(server.data, '*');
     }elseif(тут проверка, есть ли что то похожее на логин, ну например){
          document.cookie = 'login = server.data';
     }
}
if (window.addEventListener){
	window.addEventListener("message", listener,false);
} else {
	window.attachEvent("onmessage", listener);
}
</script>
Серверная часть:

PHP:
<?$key = ...generate key...; $login = 'login'?>
<script>
function listener(mes){    
    if (mes.data == 'message'){
          mes.source.postMessage('<?=$key?>', '*');
    }
    if (mes.data == '<?=$key?>'){
          mes.source.postMessage('<?=$login?>', '*');
    }
}
if (window.addEventListener){
	window.addEventListener("message", listener,false);
} else {
	window.attachEvent("onmessage", listener);
}
</script>
Скину еще раз, что с безопасностью?
 

hell0w0rd

Продвинутый новичок
todd
Мне лично ничо не понятно. В тч зачем задавать вопросы и игнорить ответы:)
 

todd

Новичок
Ну а если так? )

На клиентской части стоит блок ифрейма. (1 строка)
Как только ифрейм полностью загружен, функция post отправляет запрос message на центральный сервер. (Клиентская часть 1 - 6 строки)
Далее сервер слушает входящие сообщения. Если в них есть message, то он генерирует ключ, запоминает его и отправляет клиенту (Серверная часть 1 - 6 строки)
Клиент так же слушает входящие сообщения. Если приходит что нибудь, похожее на ключ, то он отправляет его обратно (Клиентская часть 7 - 9 строки)
Сервер вновь обрабатывает входящие сообщения, сверяет если входящее сообщение такое же, как ключ, то отправляет клиенту логин (Сервер 7 - 9 строки)
Ну а клиент в свою очередь проверяет, если сообщение похоже на логин и не похоже на ключ - заносит логин в куки (Клиент 10 - 12 строки)
 

todd

Новичок
GusakovNick
Проверил код на практике, всё работает, все написано верно. Что не так?
 

WMix

герр M:)ller
Партнер клуба
todd
я правильно понял, что ты хочешь хранить пользователя и пароль в браузере, при надобности использовать их, если нужно, к примеру, зарегиться в том или ином содержимом фрейма.
при этом боишся о том что можно прочесть переменную извне.
мне кажется что любой банер написаный на js и показаный на странице во frame может считать любую переменную в _top.
PHP:
var myVar = parent.document.anotherVar;
ну или запустить функцию :), кстати это касается flash к примеру видео с ютуба
 

todd

Новичок
fixxxer
Ок. Но это обеспечание защиты клиента ) А как защитить себя?
Я использовал твою идею с ключом. То, что я написал безопасно?
WMix
Да, всё правильно ) Ну, фиксер только что сказал, как это обойти )
 
Сверху