Как защитить глобальные переменные (окна) от перезаписи

В настоящее время я работаю над проектом, где безопасность очень важна. По умолчанию все глобальные переменные/свойства, такие как Promise или даже crypto, могут быть перезаписаны.

Есть ли способ защитить их от перезаписи?

Пример:

window.crypto.getRandomValues = () => { return [1] }

window.crypto.getRandomValues(new Uint32Array(1))[0] // 1

Моей первой мыслью было использовать Object.freeze() для блокировки объекта, но можно просто перезаписать метод Object.freeze, чтобы он ничего не делал.

Мы уже очень избирательно относимся к используемым зависимостям, но я все же хотел бы убедиться, что эти переменные нельзя перезаписать. Или, по крайней мере, определить, были ли они перезаписаны.

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

CertainPerformance 29.05.2019 10:39

возможно только правило eslint eslint.org/docs/rules/no-global-assign

Vadim Hulevich 29.05.2019 10:45

Если пользователь хочет сделать это сам, я могу с этим смириться. Но я хочу, чтобы другие библиотеки не мешали моей. Итак, если блокировка глобальных переменных невозможна, есть ли способ «изолировать» различные зависимости? Я прочитал предложение о realms. Я думаю, что это было бы то, что я ищу, но это еще не готово.

Andreas Gassmann 29.05.2019 10:56
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
373
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Отказ от ответственности: все это только грубый набросок, тщательно не проверенный. Я уверен, что есть еще проблемы, которые нужно решить.


замораживание объект-окно не вариант, это просто вызовет проблемы, но, может быть, такие объекты, как window.crypto?

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

function freezeProp(target, propertyName) {
  const { value, get = () => value, set = () => void 0, ...desc } = Object.getOwnPropertyDescriptor(target, propertyName);
  Object.defineProperty(target, propertyName, { ...desc, get, set, configurable: false });
}

freezeProp(window, "crypto");

Но эти методы работают только в том случае, если вы можете убедиться, что вы запускаете скрипт первым.

Обнаружение того, были ли изменены некоторые методы, также возможно, если у вас есть ссылка на них; и мы снова стали первым запущенным скриптом.


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

window.crypto.getRandomValues = () => {
  return [1]
};

const secure = (() => {
  let iframe = document.createElement("iframe");
  document.body.appendChild(iframe);
  const contentWindow = iframe.contentWindow;
  document.body.removeChild(iframe);
  return contentWindow;
})();

var a = window.crypto.getRandomValues(new Uint8Array(1));
console.info(a);

var b = secure.crypto.getRandomValues(new Uint8Array(1));
console.info(b);

Вы пришли к тому же выводу, что и я. Вы должны убедиться, что первый замораживает / блокирует объекты, прежде чем кто-то другой сможет что-либо перезаписать. Похоже, ваше решение работает для криптографии, но, например, «Прокси» и «Обещание» все еще могут быть перезаписаны. Моя первоначальная мысль заключалась в том, чтобы создать const safeProxy = Proxy и заблокировать его свойства, чтобы вы всегда могли полагаться на наличие safeProxy в его исходной форме. Кстати, ваш последний подход с iframe не работает, потому что можно просто перезаписать функцию document.createElement :).

Andreas Gassmann 29.05.2019 12:29

Другие вопросы по теме