Como evitar erros JavaScript relacionados à segurança

Adobe AIR 1.0 e posterior

Se você chamar um código com uso restrito em uma caixa de proteção, devido a essas restrições de segurança, o tempo de execução despachará um erro de JavaScript: "Violação de segurança de tempo de execução do Adobe AIR para código JavaScript na caixa de proteção de segurança do aplicativo." Para evitar esse erro, siga essas práticas de codificação.

Causas de erros JavaScript relacionados à segurança

O código em execução na caixa de proteção do aplicativo está restrito à maioria das operações que envolvem avaliação e execução de sequências depois que o evento load tiver sido disparado e todos os manipuladores de evento load tiverem encerrado. A tentativa de usar os seguintes tipos de instruções JavaScript que avaliam e executam strings potencialmente inseguras gera erros JavaScript:

Mapeamento de conteúdo do aplicativo para uma caixa de proteção distinta

Na maioria dos casos, você pode regravar ou reestruturar o aplicativo para evitar erros JavaScript relacionados à segurança. No entanto, quando não for possível regra ou reestruturar, você poderá carregar o conteúdo do aplicativo em uma caixa de proteção distinta usando a técnica descrita em Carregamento de conteúdo do aplicativo em uma caixa de proteção "não aplicativo" . Se esse conteúdo também deve acessar as APIs do AIR, você pode criar uma ponte de caixa de proteção, conforme descrito em Configuração de interface de ponte de caixa de proteção .

função eval()

Na caixa de proteção do aplicativo, a função eval() só pode ser usada antes do evento load da página ou durante o manipulador de eventos load . Após a página ter sido carregada, as chamadas para eval() não executarão código. No entanto, nos seguintes casos, você pode regravar o código para evitar o uso de eval() .

Atribuição de propriedades a um objeto

Em vez de analisar uma string para criar o acessador de propriedades:

eval("obj." + propName + " = " + val);

acesse propriedades com notação entre colchetes:

obj[propName] = val;

Criação de função com variáveis disponíveis no contexto

Substitua instruções como as seguintes:

function compile(var1, var2){ 
    eval("var fn = function(){ this."+var1+"(var2) }"); 
    return fn; 
}

com:

function compile(var1, var2){ 
    var self = this; 
    return function(){ self[var1](var2) }; 
}

Criação de objeto usando o nome da classe como parâmetro de sequência

Considere uma classe JavaScript hipotética definida com o seguinte código:

var CustomClass =  
    { 
        Utils: 
        { 
            Parser: function(){ alert('constructor') } 
        }, 
        Data:  
        { 
         
        } 
    }; 
var constructorClassName = "CustomClass.Utils.Parser";

A maneira mais simples de criar uma ocorrência é usar eval() :

var myObj; 
eval('myObj=new ' + constructorClassName +'()')

No entanto, você pode evitar a chamada para eval() , analisando cada componente de nome de classe e criando o novo objeto usando notação entre colchetes:

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; 
}

Para criar a ocorrência, use:

try{ 
    var Parser = getter(constructorClassName); 
    var a = new Parser(); 
    }catch(e){ 
        alert(e); 
}

setTimeout() e setInterval()

Substitua a string passada como a função do manipulador por uma referência de função ou objeto. Por exemplo, substitua uma instrução como a seguinte:

setTimeout("alert('Timeout')", 100);

com:

setTimeout(function(){alert('Timeout')}, 100); 

Ou, quando a função precisar que o objeto this seja definido pelo chamador, substitua uma instrução como:

this.appTimer = setInterval("obj.customFunction();", 100);

pelo seguinte:

var _self = this; 
this.appTimer = setInterval(function(){obj.customFunction.apply(_self);}, 100);

Construtor de funções

As chamadas para new Function(param, body) podem ser substituídas por uma declaração de função inline ou usadas apenas antes que o evento load da página tenha sido tratado.

javascript: URLs

O código definido em um link usando o javascript: O esquema de URL é ignorado na caixa de proteção do aplicativo. Não é gerado nenhum erro JavaScript inseguro. Você pode substituir links usando javascript: URLs, como:

<a href="javascript:code()">Click Me</a>

com:

<a href="#" onclick="code()">Click Me</a>

Retornos de chamada de evento atribuídos por meio de atributos onevent em instruções innerHTML e outerHTML

Ao usar innerHTML ou outerHTML para adicionar elementos ao DOM de um documento, todos os retornos de chamadas de evento atribuídos na instrução, como onclick ou onmouseover , são ignorados. Nenhum erro de segurança é gerado. Em vez disso, você pode atribuir um atributo id aos novos elementos e definir as funções de retorno de chamada do manipulador de eventos, usando o método addEventListener() .

Por exemplo, determinado um elemento de destino em um documento, como:

<div id="container"></div>

Substitua instruções como:

document.getElementById('container').innerHTML =  
    '<a href="#" onclick="code()">Click Me.</a>';

com:

document.getElementById('container').innerHTML = '<a href="#" id="smith">Click Me.</a>'; 
document.getElementById('smith').addEventListener("click", function() { code(); });

Carregamento de arquivos JavaScript externos ao diretório de instalação do aplicativo

Não é permitido o carregamento de arquivos de script externos à caixa de proteção do aplicativo. Nenhum erro de segurança é gerado. Todos os arquivos de script que são executados na caixa de proteção do aplicativo devem ser instalados no diretório do aplicativo. Para usar scripts externos em uma página, você deve mapear a página para uma caixa de proteção distinta. Consulte Carregamento de conteúdo do aplicativo em uma caixa de proteção "não aplicativo" .

document.write() e document.writeln()

As chamadas para document.write() ou document.writeln() serão ignoradas após o evento load da página ser tratado. Nenhum erro de segurança é gerado. Como alternativa, você pode carregar um novo arquivo ou substituir o corpo do documento usando técnicas de manipulação DOM.

XMLHttpRequests síncronas antes do evento load ou durante um manipulador de eventos load

As XMLHttpRequests síncronas iniciadas antes do evento load da página ou durante um manipulador de eventos load não retornam nenhum conteúdo. As XMLHttpRequests assíncronas podem ser iniciadas, mas não retornam até depois do evento load . Após o evento load ser tratado, as XMLHttpRequests síncronas se comportam normalmente.

Elementos de script criados dinamicamente

Elementos de script criados dinamicamente, como quando criados com o innerHTML ou o método document.createElement() , são ignorados.