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

UserJS. Часть 3: Безопасность

Время на прочтение2 мин
Количество просмотров1.3K
В этой статье описывается, чем опасны некоторые 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) { ... }
Теги:
Хабы:
Всего голосов 16: ↑14 и ↓2+12
Комментарии0

Публикации

Истории

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
24 сентября
Astra DevConf 2024
МоскваОнлайн
25 сентября
Конференция Yandex Scale 2024
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн