Защита от ложного URL в многопользовательских системах.

xintrea

Новичок
Защита от ложного URL в многопользовательских системах.

Здравствуйте!

Вопрос такой, подскажите куда копать.

Есть некая многопользовательская система, например игра. При логине в игру пользователь получает в куках рандомную переменную, например с именем sess_temp_uid. Наличие этой переменной в куке и в базе игры говорит о том что пользователь "валидный". (Подделку куков, время валидности, проверку reference-ссылки, проверку строки браузера и прочее пока не рассматриваем).

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

Код:
<form name="user_info" method="post" action="change_user_info.php">
 Имя
 <input id="user_name" name="user_name" type="text" size="25">
 Email
 <input id="user_email" name="user_email" type="text" size="25">
</form>
В игре есть форум, и кулхацкер разместил такую ссылку

Код:
http://game.ru/change_user_info.php?user_name=lamer&[email protected]
Если пользователь залогинен в игре, и ткнет на такую ссылку, то его данные будут изменены.

Вопрос - как от этого защититься? Достаточно ли не допускать в пространство скрипта GET-переменные, брать данные именно из POST переменных? Но тогда кулхацкер может обнулять данные... Надо еще проверять наличие всех POST переменных пусть и пустых, чтобы кулхацкер не мог обнулить данные. Достаточно ли этого?

Как вообще традиционно такая проблема решается?
 

Андрейка

Senior pomidor developer
решается добавлением в форму её "подписи", уникальной для юзера и этой формы
 

Андрейка

Senior pomidor developer
а пришедшие постом данные заведомо верные и однозначно отправлены добровольно?
 

xintrea

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

Кроме того (я точно не знаю, разубедите меня), но-помоему

1. можно сделать ссылку, содержащую JavaScript-код.
2. В JavaScript можно произвольно устанавливать POST и GET переменные в любые значения

тогда проверять откуда пришли данные (через POST или нет) недостаточно...


Мда а с подписью заморачиваться не особенно хочется... Это надо базу подписей иметь, в каждую форму вставлять hidden-поле... Добавлять код генерации и проверки... Но больше всего неудобно что нужно каждую форму защищать. Забудешь - и привет. Может более другой метод есть, который можно применить прозрачно и глобально для всего пространства игры?
 

asterisk

Новичок
в сессии храним uid юзверя.
при вводе ссылки типа:
http://game.ru/change_user_info.php?user_name=lamer&[email protected]
проверяем если session:uid != uid пользователя чьи данные изменяем:
отправляем в Бобруйск
иначе
спрашиваем действительно ли юзверь хочет изменить свои настройки ну и если ответ положительный делаем соответствующие изменения профиля.
 

xintrea

Новичок
спрашиваем действительно ли юзверь хочет изменить свои настройки ну и если ответ положительный делаем соответствующие изменения профиля.
Тогда юзверь отправит сервис в Бабруйск. Я думал сделать прозрачно для программирования, а этот подход непрозрачен не только для программирования, но и для пользователя. Подход не катит.


только POST + проверять, что referer - этот сайт
Реферер-переменные работают в 90% случаев. В оставшихся 10% они либо неподдерживаются/отключены в браузере, обрезаются файрволом пользователя, запрещены на хосте или изчезают в неизвестном направлении по неизвестным причинам. Такой подход тоже не катит.


Наверно, всеже, подписывать формы надо. Только проблемы начнутся при интегрировани flash-роликов, которые какие-то действия выполняют. Передачу подписи придется вставлять и во flash-код..
 

kruglov

Новичок
1. можно сделать ссылку, содержащую JavaScript-код.
2. В JavaScript можно произвольно устанавливать POST и GET переменные в любые значения
Нуу, если уж вы пользователям разрешаете JavaScript вставлять, то вас уже ничто не спасет. Он и странчку с формой сам откроет, и сам там на сабмит нажмет, и пароль поменяет, и аккаунт отрегистрирует... XSS во всей красе.
 

xintrea

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

Код:
<a href="javascript:document.write('<H1>Hello</H1>')">получи бонус</a>
только вместо document.write пихнуть нужный JavaScript код. Куки стоят у пользователя "валидные", а код в браузере пользователя делает свое грязное дело - устанавливает POST переменные, потом document.location("http://game.ru/change_user_info.php"), и вот данные изменены.
 

HraKK

Мудак
Команда форума
JavaScript исполняется тоже в 90% случаях. А у меня он не работает.
 

kruglov

Новичок
Нет, я имею в виду что например на форуме или там в блоге который отрекламировать, можно сделать ссылку в стиле
Не понял, злодей на вашем сайте aaa.ru вешает ссылку "дифчонки сдесь", которая ведет на bbb.ru? И уже на bbb.ru делает ссылку с JavaScript? Тогда он чужих кук не украдет.
 

xintrea

Новичок
Ну если форум дырявый на самом сайте. Или не форум, а к примеру тупая доска объявлений с неполным контролем чего там вводится. Мест, где в пространстве игры ссылу в нужном виде опубликовать можно, обычно навалом.

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

jonjonson

Охренеть
Фильтруй пользовательский ввод данных.
Например, используя данную библиотеку http://htmlpurifier.org/

Никакие формы подписывать не нужно и реферер в ОПУ.

Ввод и изменение данных нужно осуществлять только методом POST с последующим редиректом.
 

Андрейка

Senior pomidor developer
какие куки? какой фильтруйпользовательскийввод? какой методпост вместе с отключенными скриптами?


"дифчонки сдесь" http://difchonkin.ru/page.html

page.html
----
Код:
<form id="a" action="https://bank.ru/pereresti_dengi.php" method="post">
<input type=hidden name="komu" value="pupken" />
<input type=hidden name="skoka" value="1000000000000" />
<input type="image" src="gifchonka1.jpg" alt="следующая дифчонка" />
</form>
<script>document.forms['a'].submit(); </script>
 

cDLEON

Онанист РНРСlub
Создавать уникальный индефикатор для каждой формы.
Либо спрашивать у пользователя: а действительно ли он хочет что либо сделать.
Других выходаФ неД.
 

jonjonson

Охренеть
Андрейка, да, ты был прав. Но ты привёл пример Cross-Site Request Forgeries. Я вёл речь о Cross-Site Scripting, при борьбе с которым нужно либо фильтровать присланное (если нужно сохранить теги), либо (в большинстве случаев) преобразовывать символы обрабатываемые браузером специальным образом в соответствующие им html сущности.

В случае же с Cross-Site Request Forgeries для авторизованных пользователей в форму нужно добавлять скрытое поле с идентификатором сессии и проверять его наличие на стороне сервера.
 

Фанат

oncle terrible
Команда форума
А что ж никто не дал до сих пор ссылку на развеселую тему "Я верю, что нужно проверять HTTP_REFERER"? =)
 

jonjonson

Охренеть
*****, реферер однозначно отметается. Это сам топикостартер отметил :)
Реферер-переменные работают в 90% случаев. В оставшихся 10% они либо неподдерживаются/отключены в браузере, обрезаются файрволом пользователя, запрещены на хосте или изчезают в неизвестном направлении по неизвестным причинам. Такой подход тоже не катит.
 
Сверху