В этой статье описывается, чем опасны некоторые userjs трюки и как с этой опасностью справиться.
Другие статьи серии:
Опасность этой технологии очевидна. Как только Вы разрешаете доступ с некоторого адреса к расширенным возможностям (например, работать с буфером обмена), как все скрипты с этого адреса могут использовать расширенные возможности в своих целях (например, отсылать содержимое буфера на сайт — вдруг там пароль).
Решение состоит в том, чтобы разрешить доступ только одному адресу — «http://0.0.0.0/», открыть фрейм с этим адресом и все действия производить через XDM. Неудобство состоит в том, что все вызовы становятся асинхронными. Но чего не сделаешь ради безопасности. Да и есть в этом некоторый плюс — скрипты на странице не повиснут в ожидании какого-нибудь долгого синхронного вызова.
Теперь нужно обезопасить XDM.
Любой скрипт на странице может найти iframe и отправить ему сообщение. Достаточно лишь знать формат сообщений. Узнать — не проблема, если userjs выложен в сети. Да даже если userjs написан Вами и для себя, часто формат угадать несложно.
Итак, задача — сделать формат неугадываемым. Для этого нужно:
Но и этого ещё недостаточно для обеспечения безопасности.
К сожалению, userjs выполняются в контексте страницы. А значит все модификации объектов скриптами со страницы отражаются и на userjs.
Предположим, что проверка пароля в userjs производится следующим образом:
Тогда скрипт на странице может выполнить:
и получить пароль!
Необходимо сохранить функции, используемые в критических местах userjs:
Другие статьи серии:
LiveConnect
Опасность этой технологии очевидна. Как только Вы разрешаете доступ с некоторого адреса к расширенным возможностям (например, работать с буфером обмена), как все скрипты с этого адреса могут использовать расширенные возможности в своих целях (например, отсылать содержимое буфера на сайт — вдруг там пароль).
Решение состоит в том, чтобы разрешить доступ только одному адресу — «http://0.0.0.0/», открыть фрейм с этим адресом и все действия производить через XDM. Неудобство состоит в том, что все вызовы становятся асинхронными. Но чего не сделаешь ради безопасности. Да и есть в этом некоторый плюс — скрипты на странице не повиснут в ожидании какого-нибудь долгого синхронного вызова.
Теперь нужно обезопасить XDM.
XDM
Любой скрипт на странице может найти iframe и отправить ему сообщение. Достаточно лишь знать формат сообщений. Узнать — не проблема, если userjs выложен в сети. Да даже если userjs написан Вами и для себя, часто формат угадать несложно.
Итак, задача — сделать формат неугадываемым. Для этого нужно:
- для каждого пользователя сгенерировать пароль;
- добавлять в начало каждого сообщения;
- использовать событие «BeforeEvent.message», чтобы мы первым узнавали о сообщении;
- обрабатывать только сообщения с подходящим паролем;
- использовать функцию «Event.preventDefault» для предотвращения получения сообщений скриптом на странице.
Консервируем функции
Но и этого ещё недостаточно для обеспечения безопасности.
К сожалению, userjs выполняются в контексте страницы. А значит все модификации объектов скриптами со страницы отражаются и на userjs.
Предположим, что проверка пароля в userjs производится следующим образом:
if (ev.data.substring(0, password.length) == password) { ... }
Тогда скрипт на странице может выполнить:
String.prototype.substring = function(start, len) { alert(this); }
и получить пароль!
Необходимо сохранить функции, используемые в критических местах userjs:
// В самом начале скрипта. var functionCall = Function.prototype.call; var stringSubstring = String.prototype.substring; // В обработчике события. stringSubstring.call = functionCall; if (stringSubstring.call(ev.data, 0, password.length) == password) { ... }