Jeśli wywołany zostanie kod, którego użycie zostało ograniczone ze względu na ograniczenia bezpieczeństwa, środowisko wykonawcze zgłosi błąd JavaScript o następującej treści: „Naruszenie zabezpieczeń środowiska wykonawczego Adobe AIR dla kodu JavaScript w obszarze izolowanym zabezpieczeń aplikacji”. Aby uniknąć tego błędu, należy zastosować poniższe praktyki kodowania.
Przyczyny błędów JavaScript związanych z bezpieczeństwem
Dostęp kodu wykonywanego w obszarze izolowanym aplikacji jest ograniczony dla większości operacji, które dotyczą interpretacji i wykonania ciągów znaków po uruchomieniu zdarzenia
load
dokumentu i zakończenia działania dowolnego modułu obsługi zdarzeń
load
. Próba użycia poniższych typów instrukcji JavaScript, które interpretują i wykonują potencjalnie niebezpieczne ciągi znaków generują błędy JavaScript:
Odwzorowywanie treści aplikacji w różnych obszarach izolowanych
eval(), funkcja
W obszarze izolowanym aplikacji funkcja
eval()
może być używana jedynie przed zdarzeniem
load
strony lub w czasie działania modułu obsługi zdarzeń
load
. Po załadowaniu strony wywołanie funkcji
eval()
nie spowoduje wykonania kodu. Jednak w poniższych przypadkach można ponownie napisać kod, aby uniknąć użycia funkcji
eval()
.
Przypisywanie właściwości do obiektu
Zamiast przekształcać ciąg znaków w celu utworzenia akcesora właściwości:
eval("obj." + propName + " = " + val);
do dostępu do właściwości należy użyć notacji z nawiasami:
obj[propName] = val;
Tworzenie funkcji ze zmiennymi dostępnymi kontekstowo
Zastąp instrukcje w następujący sposób:
function compile(var1, var2){
eval("var fn = function(){ this."+var1+"(var2) }");
return fn;
}
na:
function compile(var1, var2){
var self = this;
return function(){ self[var1](var2) };
}
Tworzenie obiektu z użyciem nazwy klasy jako parametru w postaci ciągu znaków
Rozważmy hipotetyczną klasę JavaScript zdefiniowaną za pomocą poniższego kodu:
var CustomClass =
{
Utils:
{
Parser: function(){ alert('constructor') }
},
Data:
{
}
};
var constructorClassName = "CustomClass.Utils.Parser";
Najprostszym sposobem na utworzenie instancji będzie użycie funkcji
eval()
:
var myObj;
eval('myObj=new ' + constructorClassName +'()')
Można jednak uniknąć wywołania funkcji
eval()
przez przekształcenie każdego składnika o danej nazwie klasy i utworzenie nowego obiektu za pomocą notacji z nawiasami:
function getter(str)
{
var obj = window;
var names = str.split('.');
for(var i=0;i<names.length;i++){
if(typeof obj[names[i]]=='undefined'){
var undefstring = names[0];
for(var j=1;j<=i;j++)
undefstring+="."+names[j];
throw new Error(undefstring+" is undefined");
}
obj = obj[names[i]];
}
return obj;
}
Aby utworzyć instancję, użyj:
try{
var Parser = getter(constructorClassName);
var a = new Parser();
}catch(e){
alert(e);
}
setTimeout() i setInterval()
Zastąp ciąg znaków przekazany jako funkcja modułu obsługi odwołaniem funkcji lub obiektem. Na przykład: zastąp instrukcję:
setTimeout("alert('Timeout')", 100);
na:
setTimeout(function(){alert('Timeout')}, 100);
Lub jeśli funkcja wymaga, aby obiekt
this
był ustawiony przez obiekt wywołujący, zastąp instrukcję:
this.appTimer = setInterval("obj.customFunction();", 100);
na następującą:
var _self = this;
this.appTimer = setInterval(function(){obj.customFunction.apply(_self);}, 100);
Konstruktor funkcji
Wywołanie
new Function(param, body)
można zastąpić dołączoną deklaracją funkcji lub użyć go wyłącznie przed obsługą zdarzenia
load
strony.
Adresy URL javascript:
Kod zdefiniowany w łączu za pomocą schematu URL javascript: jest ignorowany w obszarze izolowanym aplikacji. Nie jest generowany żaden niebezpieczny błąd JavaScript. Łącza można zastąpić za pomocą adresów URL javascript: w sposób przedstawiony poniżej:
<a href="javascript:code()">Click Me</a>
na:
<a href="#" onclick="code()">Click Me</a>
Wywołania zwrotne zdarzenia przypisane za pomocą atrybutu onevent w instrukcjach innerHTML i outerHTML
Korzystając z instrukcji innerHTML lub outerHTML do dodawania elementów do modelu DOM dokumentu, dowolne wywołania zwrotne zdarzenia przypisanego w instrukcji (np.
onclick
lub
onmouseover
) zostaną zignorowane. Nie zostanie wygenerowany żaden błąd dotyczący zabezpieczeń. Zamiast tego można przypisać atrybut
id
do nowych elementów i ustawić funkcje wywołania zwrotnego dla modułu obsługi zdarzeń za pomocą metody
addEventListener()
.
Na przykład: dany element docelowy w dokumencie:
<div id="container"></div>
Zastępuje instrukcje:
document.getElementById('container').innerHTML =
'<a href="#" onclick="code()">Click Me.</a>';
na:
document.getElementById('container').innerHTML = '<a href="#" id="smith">Click Me.</a>';
document.getElementById('smith').addEventListener("click", function() { code(); });
Ładowanie plików JavaScript spoza katalogu instalacyjnego aplikacji
Ładowanie plików skryptu spoza obszaru izolowanego aplikacji jest niedozwolone. Nie zostanie wygenerowany żaden błąd dotyczący bezpieczeństwa. Wszystkie pliki skryptu, które uruchamiane są w obszarze izolowanym aplikacji, muszą być zainstalowane w katalogu aplikacji. Aby użyć zewnętrznych skryptów na stronie, należy odwzorować stronę w innym obszarze izolowanym. Patrz
Wczytywanie zawartości aplikacji do obszaru izolowanego niezwiązanego z aplikacjami
.
document.write() i document.writeln()
Wywołania metod
document.write()
lub
document.writeln()
są ignorowane po obsłużeniu zdarzenia
load
strony. Nie zostanie wygenerowany żaden błąd dotyczący zabezpieczeń. Alternatywnym rozwiązaniem jest załadowanie nowego pliku lub zastąpienie treści dokumentu przy pomocy technik manipulowania DOM.
Synchroniczne XMLHttpRequests przed zdarzeniem load lub w czasie działania modułu obsługi zdarzenia load
Synchroniczne XMLHttpRequests zainicjowane przed zdarzeniem
load
strony lub w czasie działania modułu obsługi zdarzeń
load
nie zwracają żadnej treści. Asynchroniczne XMLHttpRequests można zainicjować, ale nie zwrócą żadnej treści dopóki nie zostanie zakończone zdarzenie
load
. Po obsłużeniu zdarzenia
load
synchroniczne XMLHttpRequests działają zwyczajnie.
Dynamicznie utworzone elementy skryptu
Dynamicznie utworzone elementy skryptu, np. elementy utworzone z właściwością innerHTML lub za pomocą metody
document.createElement()
, są ignorowane.
|
|
|