Вопросы безопасности закладки, CSRF, хешированный ключ

Мой букмарклет можно вызывать с любого сайта и в принципе позволяет пользователю вставлять строку в свою коллекцию издалека - если он вошел в систему.

Теперь я хочу включить защиту CSRF для моего сайта, и поскольку букмарклет - это в основном не поддельный запрос на межсайтовый сайт, я подумал о том, как я могу отличить его от поддельных.
Это не среда высокой безопасности, но я также заинтересован в принципе.

Я подумал, что у меня есть способ сделать это, но потом понял, что у него проблемы в изобилии.

Оригинальная идея

  • сгенерируйте случайный ключ, который включен в ссылку labellet. Хэш ключа сохраняется в базе данных. Случайный ключ позволяет ТОЛЬКО доступ к привилегии вставки в эту коллекцию и не может использоваться нигде.
  • букмарклет загружает более длинный script с моего сервера, поэтому я могу предоставить токен предотвращения CSRF таким образом
  • требуется, чтобы пользователь вошел в систему

Проблемы

  • Если у меня есть ключ букмарклета, нужны ли мне токены CSRF?
  • Есть ли способ защитить ключ букмарклета, если пользователь нажимает свой букмарклет на вредоносный веб-сайт?
  • Я не хочу, чтобы имя пользователя и пароль сохранялись в ссылке букмарклета, потому что любой, у кого есть доступ к компьютеру, также получит пароль, поэтому я решил использовать случайный ключ.
    • но если я храню только хеш, я не могу создать одну и ту же ссылку букмарклета дважды, поэтому, когда пользователю нужен букмарклет в другом браузере/компьютере, ему утомительно нужно импортировать ссылку из старой или отменить поддержку старого.
    • но я не должен хранить ключ cleartext, потому что тот, кто получает доступ к базе данных, может использовать этот ключ для вставки строк в не принадлежащие ему аккаунты.
    • Возможное решение. Я могу попросить пользователя предоставить его пароль в любое время, когда он создаст букмарклет и хеширует пароль много раз и помещает этот хэш в URL-адрес и помещает хэш этой хэш моей базы данных. Но, конечно, это открывает гораздо более серьезные дыры в безопасности.
      • Я мог бы сделать это с чем-то вроде "Девы Марии" вместо
      • Я не могу использовать bcrypt для хэширования из-за случайной соли, не так ли? Какая хэш-функция была бы правильной? Или вы упустили бы всю идею?
  • Если я оставлю ключ букмарклета, вредоносный веб-сайт может просто вставить букмарклет и извлечь из него действительный токен CSRF, правильно?

Лучшие идеи? Или вы не можете иметь CSR без F?


Изменить, указанный пример использования

Одна вещь, о которой я просто не думал, - это использование iframe, предложенное Шрипати Кришнаном.

Я не указал свой вариант использования, так что да, iframe - это правильное решение для вышеупомянутого проблема.

Однако на самом деле мой букмарклет на данный момент выполняет некоторое базовое взаимодействие с веб-сайтом во время выполнения (это означает, что форма уже существует, и пользователь может изменить свой выбор на сайте DOM, который должен изменить форму). Я готов уволить эту функциональность для моего варианта использования, если окажется, что нет разумно-безопасного способа рассказать обо всем, кроме как подделанные запросы на межсайтовый сайт, но меня все еще интересует теоретический уровень.

Ответ 1

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

Предположим, что ваша служба позволяет пользователям добавлять любые страницы, которые он пожелает. Задачей букмарклета было бы сохранить {url, title} в базе данных. В то же время вы хотите, чтобы вредоносный веб-сайт автоматически сохранял URL-адреса для пользователя, который вошел в систему.

Вот что я сделал бы, чтобы решить это -

  • Создайте страницу в своем домене, которая имеет стандартную форму html с регулярной защитой CSRF. Эта страница принимает параметры {url, pagetitle}, но сохраняет только этот кортеж, когда пользователь явно нажимает кнопку "Сохранить".
  • Задача букмарклета - загрузить iframe
  • После загрузки iframe его обычный запрос с тем же исходным кодом

Это более или менее то, что читатель Google делает как часть своего букмарклета. Вот код для его букмарклета - обратите внимание, что у него нет никаких токенов


javascript:
var b=document.body;
var GR________bookmarklet_domain='http://www.google.com';
if(b&&!document.xmlVersion) {
  void(z=document.createElement('script'));
  void(z.src='http://www.google.com/reader/ui/link-bookmarklet.js');
  void(b.appendChild(z));
 }
 else{}

ИЗМЕНИТЬ: Вы все равно можете поддерживать взаимодействие с подходом iframe. Запуск буклета выполняется в контексте веб-сайта, поэтому он имеет доступ к DOM. Вы можете взаимодействовать, тем не менее, с веб-сайтом. Когда вы будете готовы к сохранению, откройте Iframe. IFrame будет своего рода экраном подтверждения с помощью одной кнопки сохранения.

Трюк заключается в том, чтобы отложить создание iframe. Вы только создаете iframe, когда пользователь готов к сохранению.

Ответ 2

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

Если букмарклет происходит от стороннего сайта, то вы ничего не можете сделать. Это определение CSRF.