Wiki-учебник по веб-технологиям: JavaScript/ПодсказкиДляНаписанияБезопасногоJavaScript ...

Главная | Каталог |

Проверка размещения скрипта


Если вы промаркировали скрипты на страницах, размещённых на вашем сайте, можно скопировать JAR-файл с вашего сайта и поместить его на другой сайт. Поскольку сами по себе маркированные скрипты не изменились, они будут продолжать работу под вашей подписью.

Если вы хотите предотвратить это, вы может заставить ваши скрипты работать только с вашего сайта.

<SCRIPT ARCHIVE="siteSpecific.jar" ID="a" LANGUAGE="JavaScript1.2">
if (document.URL.match(/^http:\/\/www.company.com\//)) {
   netscape.security.PrivilegeManager.enablePrivilege(...);
   // здесь начинка скрипта
}
</SCRIPT>


Тогда, если JAR-файл и скрипт скопированы на другой сайт, они не будут больше работать. Если тот, кто скопировал скрипт, изменит его, чтобы обойти проверку источника скрипта, подпись дезавуируется.

Будьте осторожны с тем, что экспортируете

Когда вы экспортируете функцию из вашего маркированного скрипта, вы фактически передаёте доверительное пользование любому скрипту, вызывающему вашу функцию. Это означает, что вы несёте ответственность за то, что экспортируете интерфейсы, которые могут использоваться нежелательным образом. Например, следующая программа экспортирует вызов eval, который может работать под расширенными привилегиями.

<SCRIPT ARCHIVE="duh.jar" ID="a">
function myEval(s) {
   netscape.security.PrivilegeManager.enablePrivilege(
      "UniversalFileAccess");
   return eval(s);
}
export myEval; // НЕ ДЕЛАЙТЕ ЭТОГО!!!!
</SCRIPT>


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

Минимизация Trusted Code Base

На жаргоне системы безопасности, trusted code base (TCB) это набор кода, имеющий привилегии для выполнения ограниченных акций. Одним из путей повышения безопасности является уменьшение размера TCB, что даст меньше возможностей для атак или ошибок.

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

<SCRIPT ARCHIVE="historyWin.jar" ID="a">
netscape.security.PrivilegeManager.enablePrivilege(
   "UniversalBrowserAccess");
var win = window.open();
for (var i=0; i < history.length; i++) {
   win.document.writeln(history[i] + "<BR>");
}
win.close();
</SCRIPT>


TCB в этом примере это весь скрипт, поскольку выданы в начале и нигде не отменяются. Вы можете уменьшить TCB, переписав программу так:

<SCRIPT ARCHIVE="historyWin.jar" ID="a">
var win = window.open();
netscape.security.PrivilegeManager.enablePrivilege(
   "UniversalBrowserAccess");
for (var i=0; i < history.length; i++) {
   win.document.writeln(history[i] + "<BR>");
}
netscape.security.PrivilegeManager.revertPrivilege(
   "UniversalBrowserAccess");
win.close();
</SCRIPT>


После этого TCB – это только цикл, содержащий доступ к свойству history. Вы можете исключить излишние вызовы Java, изменяя привилегию с помощью ввода функции:

<SCRIPT ARCHIVE="historyWin.jar" ID="a">
function writeArray() {
   netscape.security.PrivilegeManager.enablePrivilege(
      "UniversalBrowserAccess");
   for (var i=0; i < history.length; i++) {
      win.document.writeln(history[i] + "<BR>");
   }
}
var win = window.open();
writeArray();
win.close();
</SCRIPT>


Привилегии автоматически изменяются, когда writeArray возвращает управление, поэтому вам нет необходимости делать это явным образом.

Использование минимума, необходимого для решения задачи

Другой способ уменьшить возможность проникновения и возникновения ошибок – использовать только необходимый минимум, необходимый для выполнения данного доступа. Например, предыдущий код запрашивал UniversalBrowserAccess, которая является целевым макросом, содержащим UniversalBrowserRead и UniversalBrowserWrite. Только UniversalBrowserRead требуется для чтения элементов из массива history, поэтому вы может переписать вышеприведённый код и сделать его более безопасным:

<SCRIPT ARCHIVE="historyWin.jar" ID="a">
function writeArray() {
   netscape.security.PrivilegeManager.enablePrivilege(
      "UniversalBrowserRead");
   for (var i=0; i < history.length; i++) {
      win.document.writeln(history[i] + "<BR>");
   }
}
var win = window.open();
writeArray();
win.close();
</SCRIPT>