O modelo de segurança de tempo de execução isola o código de origens distintas. Cruzando scripts de conteúdo em caixas de proteção de segurança distintas, você pode permitir que o conteúdo de uma caixa de proteção de segurança acesse as propriedades e os métodos selecionados em outra caixa de proteção.
Caixas de proteção de segurança do AIR e código JavaScript
O AIR aplica a política de mesma origem, que impede a interação de código de um domínio com o conteúdo de outro domínio. Todos os arquivos são colocados em uma caixa de proteção com base nas respectivas origens. Normalmente, o conteúdo na caixa de proteção do aplicativo não pode violar o princípio de mesma origem e o conteúdo cross-scripting, carregado de fora do diretório de instalação do aplicativo. No entanto, o AIR oferece algumas técnicas que permitem o cruzamento de scripts em conteúdo "não aplicativo".
Uma das técnicas usa frames ou iframes para mapear conteúdo de aplicativo em uma caixa de proteção de segurança distinta. Qualquer página carregada da área com caixa de proteção do aplicativo se comporta como se tivesse sido carregada do domínio remoto. Por exemplo, mapeando o conteúdo do aplicativo para o domínio
example.com
, esse conteúdo pode fazer o cruzamento cross-scripting das páginas carregadas desse domínio.
Como essa técnica coloca o conteúdo do aplicativo em uma caixa de proteção distinta, o código nesse conteúdo também não estará mais sujeito às restrições na execução de código em strings avaliadas. Você pode usar essa técnica de mapeamento de caixa de proteção para para atenuar essas restrições, mesmo quando não for necessário fazer o cruzamento de scripts de conteúdo remoto. Mapear conteúdo dessa maneira pode ser muito útil ao trabalhar com uma das várias estruturas JavaScript ou com código existente que dependa das strings de avaliação. No entanto, você deve considerar e se proteger contra o risco adicional de que algum conteúdo não confiável possa ser injetado e executado quando o conteúdo for executado fora da caixa de proteção do aplicativo.
Ao mesmo tempo, o conteúdo de aplicativo mapeado para uma outra caixa de proteção perde o acesso às APIs do AIR, portanto, a técnica de mapeamento de caixa de proteção não pode ser usada para expor a funcionalidade do AIR ao código executado fora da caixa de proteção do aplicativo.
Outra técnica de cruzamento de scripts permite criar uma interface chamada
ponte de caixa de proteção
entre o conteúdo de uma caixa de proteção "não aplicativo" e seu documento pai na caixa de proteção do aplicativo. A ponte permite que o conteúdo filho acesse as propriedades e os métodos definidos pelo pai e o pai acesse as propriedades e os métodos definidos pelo filho, ou ambos.
Por fim, você também pode executar XMLHttpRequests entre domínios da caixa de proteção do aplicativo e, opcionalmente, de outras caixas de proteção.
Para obter mais informações, consulte
Elementos HTML frame e iframe
,
Segurança HTML no Adobe AIR
e
O objeto XMLHttpRequest
.
Carregamento de conteúdo do aplicativo em uma caixa de proteção "não aplicativo"
Para permitir que o conteúdo do aplicativo faça cruzamento de script de conteúdo carregado de fora do diretório de instalação do aplicativo, você pode usar os elementos
frame
ou
iframe
para carregar conteúdo do aplicativo na mesma caixa de proteção de segurança do conteúdo externo. Se você não precisa fazer cruzamento de script de conteúdo remoto, mas ainda assim deseja carregar uma página do seu aplicativo fora da respectiva caixa de proteção, pode usar a mesma técnica, especificando
http://localhost/
ou algum outro valor inócuo, como o domínio de origem.
O AIR adiciona os novos atributos
sandboxRoot
e
documentRoot
ao elemento frame que permite especificar se o arquivo do aplicativo carregado no frame deve ser mapeado para uma caixa de proteção "não aplicativo". Arquivos que estão sendo resolvidos em um caminho abaixo da URL
sandboxRoot
são carregados, em vez do diretório
documentRoot
. Para fins de segurança, o conteúdo do aplicativo carregado dessa maneira é tratado como se na verdade tivesse sido carregado da URL
sandboxRoot
.
A propriedade
sandboxRoot
especifica a URL que deve ser usada para determinar a caixa de proteção e o domínio em que o conteúdo do quadro deve ser colocado. Os esquemas de URL
file:
,
http:
ou
https:
devem ser usados. Se você especificar uma URL relativa, o conteúdo permanecerá na caixa de proteção do aplicativo.
A propriedade
documentRoot
especifica o diretório do qual o conteúdo do quadro deve ser carregado. Os esquemas de URL
file:
,
app:
ou
app-storage:
devem ser usados.
O exemplo a seguir mapeia o conteúdo instalado no subdiretório
sandbox
do aplicativo a ser executado na caixa de proteção remota e o domínio
www.example.com
:
<iframe
src="http://www.example.com/local/ui.html"
sandboxRoot="http://www.example.com/local/"
documentRoot="app:/sandbox/">
</iframe>
A página
ui.html
pode carregar um arquivo javascript da pasta
sandbox
local, usando a seguinte tag de script:
<script src="http://www.example.com/local/ui.js"></script>
Ele também pode carregar conteúdo de um diretório no servidor remoto usando uma tag de script como a que segue:
<script src="http://www.example.com/remote/remote.js"></script>
A URL
sandboxRoot
irá mascarar todo conteúdo na mesma URL do servidor remoto. No exemplo anterior, você não podia acessar nenhum conteúdo remoto em
www.example.com/local/
(ou qualquer um de seus subdiretórios), pois o AIR remapeia a solicitação para o diretório local do aplicativo. As solicitações são remapeadas, sejam elas derivadas de navegação de página, de uma XMLHttpRequest ou de qualquer outro meio de carregamento de conteúdo.
Configuração de interface de ponte de caixa de proteção
Você pode usar uma ponte de caixa de proteção quando o conteúdo da caixa de proteção do aplicativo tiver que acessar propriedades ou métodos definidos pelo conteúdo em uma caixa de proteção "não aplicativo" , ou quando o conteúdo "não aplicativo" tiver que acessar propriedades e métodos definidos pelo conteúdo na caixa de proteção do aplicativo. Crie uma ponte com as propriedades
childSandboxBridge
e
parentSandboxBridge
do objeto
window
de algum documento filho.
Estabelecimento de uma ponte de caixa de proteção filha
A propriedade
childSandboxBridge
permite que o documento filho exponha uma interface para o conteúdo do documento pai. Para expor uma interface, você define a propriedade
childSandbox
como função ou objeto no documento filho. Em seguida, você pode acessar o objeto ou função do conteúdo no documento pai. O exemplo a seguir mostra como um script que está sendo executado em um documento filho pode expor um objeto contendo uma função e uma propriedade para o respectivo pai:
var interface = {};
interface.calculatePrice = function(){
return ".45 cents";
}
interface.storeID = "abc"
window.childSandboxBridge = interface;
Se esse filho foi carregado em um iframe com id "filho" atribuída, você poderá acessar a interface do conteúdo pai, lendo a propriedade
childSandboxBridge
do quadro:
var childInterface = document.getElementById("child").contentWindow.childSandboxBridge;
air.trace(childInterface.calculatePrice()); //traces ".45 cents"
air.trace(childInterface.storeID)); //traces "abc"
Estabelecimento de uma ponte de caixa de proteção pai
A propriedade
parentSandboxBridge
permite que o documento pai exponha uma interface para o conteúdo do documento filho. Para expor uma interface, o documento pai define a propriedade
parentSandbox
do documento filho como uma função ou objeto definido no documento pai. Em seguida, você pode acessar o objeto ou função do conteúdo no filho. O exemplo a seguir mostra como um script que está sendo executado em um quadro pai pode expor um objeto contendo uma função para um documento filho:
var interface = {};
interface.save = function(text){
var saveFile = air.File("app-storage:/save.txt");
//write text to file
}
document.getElementById("child").contentWindow.parentSandboxBridge = interface;
Ao usar essa interface, o conteúdo do quadro filho poderá salvar texto em um arquivo chamado
save.txt
, mas não terá nenhum outro acesso ao sistema de arquivos. O conteúdo filho poderá chamar a função save da seguinte maneira:
var textToSave = "A string.";
window.parentSandboxBridge.save(textToSave);
O conteúdo do aplicativo deverá expor a interface mais estreita possível para as outras caixas de proteção. O conteúdo "não aplicativo" deve ser considerado não confiável inerentemente, já que ele pode estar sujeito à injeção de código acidental ou mal-intencionado. Você deve colocar as proteções apropriadas no local para impedir o uso inadequado da interface exposta através da ponte da caixa de proteção pai.
Acesso à ponte de caixa de proteção pai durante o carregamento de página
Para que o script de um documento filho acesse uma ponte de caixa de proteção pai, a ponte deve ser configurada antes que o script seja executado. Os objetos window, frame e iframe despacham o evento
dominitialize
quando uma nova página DOM tiver sido criada, mas antes que qualquer script tenha sido analisado ou que elementos DOM tenham sido adicionados. Você pode usar o evento
dominitialize
para estabelecer a ponte na sequência de construção de página, cedo o bastante para que todos os scripts no documento filho possam acessá-la.
O exemplo a seguir ilustra como criar uma ponte de caixa de proteção pai em resposta ao evento
dominitialize
despachado do quadro filho:
<html>
<head>
<script>
var bridgeInterface = {};
bridgeInterface.testProperty = "Bridge engaged";
function engageBridge(){
document.getElementById("sandbox").contentWindow.parentSandboxBridge = bridgeInterface;
}
</script>
</head>
<body>
<iframe id="sandbox"
src="http://www.example.com/air/child.html"
documentRoot="app:/"
sandboxRoot="http://www.example.com/air/"
ondominitialize="engageBridge()"/>
</body>
</html>
O seguinte documento
child.html
ilustra como o conteúdo filho pode acessar a ponte de caixa de proteção pai:
<html>
<head>
<script>
document.write(window.parentSandboxBridge.testProperty);
</script>
</head>
<body></body>
</html>
Para ouvir o evento
dominitialize
em uma janela filha, em vez de um quadro, você deve adicionar o ouvinte ao novo objeto window filho criado pela função
window.open()
:
var childWindow = window.open();
childWindow.addEventListener("dominitialize", engageBridge());
childWindow.document.location = "http://www.example.com/air/child.html";
Nesse caso, não há como mapear o conteúdo do aplicativo para uma caixa de proteção "não aplicativo". Essa técnica só é útil quando
child.html
é carregado de fora do diretório do aplicativo. Você pode ainda mapear conteúdo do aplicativo na janela para uma caixa de proteção "não aplicativo", mas primeiramente, é preciso carregar uma página intermediária que use ela mesma quadros para carregar o documento filho e mapeá-lo para a caixa de proteção desejada.
Se você usar a função
createRootWindow()
da classe HTMLLoader para criar uma janela, a nova janela não será filha do documento do qual
createRootWindow()
será chamado. Portanto, você não pode criar uma ponte de caixa de proteção da janela que faz a chamada para um conteúdo "não aplicativo" carregado na nova janela. Em vez disso, você deve carregar uma página intermediária na nova janela que use ela mesma quadros para carregar o documento filho. Em seguida, você pode estabelecer a ponte do documento pai da nova janela para o documento filho carregado no quadro.
|
|
|