Uso de scripts entre contenidos en diferentes entornos limitados de seguridad

Adobe AIR 1.0 y posterior

El modelo de seguridad de motor de ejecución aísla el código de diferentes orígenes. Al utilizar scripts entre contenidos en diferentes entornos limitados de seguridad, se puede permitir que el contenido de un entorno limitado de seguridad acceda a los métodos y propiedades seleccionadas en otro entorno limitado.

Entornos limitados de seguridad de AIR y código JavaScript

AIR aplica una política de mismo origen que impide que el código en un dominio interactúe con el contenido en otro. Todos los archivos se colocan en un entorno limitado basado en su origen. Normalmente, el contenido en el entorno limitado de la aplicación no puede infringir el principio de mismo origen y uso de scripts entre contenidos cargados desde fuera del directorio de instalación de la aplicación. Sin embargo, AIR proporciona algunas técnicas que permiten el uso de scripts entre contenidos que no pertenecen a la aplicación.

Una técnica utiliza fotogramas o iframes para asignar el contenido de aplicación en un entorno limitado de seguridad diferente. Cualquier página que se carga desde el área del entorno limitado de la aplicación se comporta como si se cargara desde el dominio remoto. Por ejemplo, al asignar el contenido de aplicación al dominio example.com , dicho contenido podría hacer uso de scripts entre páginas desde example.com.

Dado que esta técnica coloca el contenido de aplicación en un entorno limitado diferente, el código dentro de dicho contenido tampoco está sujeto a las restricciones de ejecución de código en cadenas evaluadas. Se puede utilizar esta técnica de asignación de entorno limitado para facilitar estas restricciones aun cuando no necesita un contenido remoto de uso de scripts entre contenidos. La asignación de contenido en este modo puede ser especialmente útil cuando se trabaja con una de las muchas arquitecturas de JavaScript o con código existente que depende de cadenas de evaluación. Sin embargo, se debe considerar y estar atento al riesgo adicional de que el contenido sospechoso se podría insertar y ejecutar cuando el contenido se ejecuta fuera del entorno limitado de la aplicación.

Del mismo modo, el contenido de aplicación asignado a otro entorno limitado pierde el acceso a las API de AIR, por lo que la técnica de asignación de entorno limitado no se puede utilizar para exponer la funcionalidad de AIR al código ejecutado fuera del entorno limitado de la aplicación.

Otra técnica del uso de scripts entre contenidos permite crear una interfaz denominada puente de entorno limitado entre el contenido en un entorno limitado que no pertenece a la aplicación y el documento principal en el entorno limitado de la aplicación. El puente permite que el elemento secundario acceda a las propiedades y métodos definidos por el elemento principal, que el elemento principal acceda a las propiedades y a los métodos definidos por el elemento secundario o ambos.

También se puede realizar XMLHttpRequests entre dominios desde el entorno limitado de la aplicación y, opcionalmente, desde otros entornos limitados.

Para más información, consulte Elementos frame e iframe de HTML , Seguridad HTML en Adobe AIR y Objeto XMLHttpRequest .

Carga de contenido de aplicación en un entorno limitado que no pertenece a la aplicación

Para permitir que el contenido de aplicación use scripts entre contenidos cargados fuera del directorio de instalación de la aplicación, se pueden utilizar los elementos frame o iframe para cargar el contenido de aplicación en el mismo entorno limitado de seguridad que el contenido externo. Si no necesita usar el script entre contenido remoto, pero aún desea cargar una página de su aplicación fuera del entorno limitado de la aplicación, puede usar la misma técnica, especificando http://localhost/ o cualquier otro valor inofensivo como el dominio de origen.

AIR añade los nuevos atributos, sandboxRoot y documentRoot , al elemento frame que permite especificar si el archivo de aplicación cargado en el fotograma se debe asignar a un entorno limitado que no pertenece a la aplicación. Los archivos que se resuelven en una ruta debajo de la URL sandboxRoot se cargan desde el directorio documentRoot . Por razones de seguridad, el contenido de aplicación cargado de este modo se lo trata como si se cargara desde una URL sandboxRoot .

La propiedad sandboxRoot especifica la URL que se debe utilizar para determinar el entorno limitado y dominio donde colocar el contenido del fotograma. Se deben utilizar los esquemas de URL file: , http: o https: . Si se especifica una URL relativa, el contenido permanece en el entorno limitado de la aplicación.

La propiedad documentRoot especifica el directorio desde donde cargar el contenido de fotograma. Se deben utilizar los esquemas de URL file: , app: o app-storage: .

En el siguiente ejemplo se asigna el contenido instalado en el subdirectorio sandbox de la aplicación para que se ejecute en el entorno limitado remoto y en el dominio www.example.com :

<iframe 
    src="http://www.example.com/local/ui.html"  
    sandboxRoot="http://www.example.com/local/"  
    documentRoot="app:/sandbox/"> 
</iframe>

La página ui.html podría cargar un archivo javascript desde la carpeta local sandbox utilizando la siguiente etiqueta de script:

<script src="http://www.example.com/local/ui.js"></script>

Asimismo, podría cargar el contenido desde un directorio en el servidor remoto utilizando una etiqueta de script como la siguiente:

<script src="http://www.example.com/remote/remote.js"></script>

La URL sandboxRoot enmascara cualquier contenido en la misma URL en el servidor remoto. En el ejemplo anterior, no se podría acceder a ningún contenido remoto en www.example.com/local/ (ni a ninguno de los subdirectorios) dado que AIR vuelve a asignar la petición al directorio local de la aplicación. Se vuelven a asignar las peticiones independientemente si derivan de la navegación de una página, de XMLHttpRequest o de cualquier otro medio de carga de contenido.

Definición de una interfaz de puente de entorno limitado

Puede utilizar un puente de entorno limitado cuando el contenido en el entorno limitado de la aplicación debe acceder a las propiedades o métodos definidos por el contenido en un entorno limitado que no pertenece a la aplicación o cuando el contenido que no pertenece a la aplicación debe acceder a las propiedades y métodos definidos por el contenido en el entorno limitado de la aplicación. Cree un puente con las propiedades childSandboxBridge y parentSandboxBridge del objeto window de cualquier documento secundario.

Definición de un puente de entorno limitado secundario

La propiedad childSandboxBridge permite que el documento secundario exponga una interfaz al contenido en el documento principal. Para exponer una interfaz, se debe definir la propiedad childSandbox a una función u objeto en el documento secundario. Entonces puede acceder al objeto o función desde el contenido en el documento principal. En el siguiente ejemplo se muestra el modo en que un script ejecutándose en un documento secundario puede exponer al documento principal un objeto que contiene una función y una propiedad:

var interface = {}; 
interface.calculatePrice = function(){ 
    return ".45 cents"; 
} 
interface.storeID = "abc" 
window.childSandboxBridge = interface;

Si este contenido secundario se cargó en un iframe y se le asignó un ID de “elemento secundario”, se puede acceder a la interfaz desde el contenido principal leyendo la propiedad childSandboxBridge del fotograma:

var childInterface = document.getElementById("child").contentWindow.childSandboxBridge; 
air.trace(childInterface.calculatePrice()); //traces ".45 cents" 
air.trace(childInterface.storeID)); //traces "abc"

Definición de un puente de entorno limitado principal

La propiedad childSandboxBridge permite que el documento secundario exponga una interfaz al contenido en el documento principal. Para exponer una interfaz, el documento principal define la propiedad parentSandbox del documento secundario a una función u objeto definido en el documento principal. Entonces puede acceder al objeto o función desde el contenido en el documento secundario. En el siguiente ejemplo se muestra el modo en que un script ejecutándose en un fotograma principal puede exponer al documento secundario un objeto que contiene una función:

var interface = {}; 
interface.save = function(text){ 
    var saveFile = air.File("app-storage:/save.txt"); 
    //write text to file 
} 
document.getElementById("child").contentWindow.parentSandboxBridge = interface;

Utilizando esta interfaz, el contenido en un fotograma secundario puede guardar el texto en un archivo denominado save.txt , pero no tiene ningún otro acceso al sistema de archivos. El contenido secundario puede llamar a la función save de la siguiente manera:

var textToSave = "A string."; 
window.parentSandboxBridge.save(textToSave);

El contenido de aplicación debe exponer una interfaz lo más limitada posible a otros entornos limitados. Se debería considerar el contenido que no pertenece a la aplicación intrínsicamente sospechoso ya que puede estar sujeto a la inserción de código accidental o malintencionado. Se debe establecer una protección adecuada para evitar el mal uso de la interfaz que se expone a través del puente de entorno limitado principal.

Acceso de un puente de entorno limitado principal durante la carga de una página

Para que un script en un documento secundario acceda a un puente de entorno limitado principal, se debe definir el puente antes de ejecutar el script. Los objetos Window, frame e iframe distribuyen un evento dominitialize cuando se crea un nuevo DOM de página, pero antes de que se haya analizado un script o se hayan añadido elementos DOM. Se puede utilizar el evento dominitialize para establecer el puente con suficiente anticipación en la secuencia de construcción de la página al que pueden acceder todos los scripts en documento secundario.

En el siguiente ejemplo se muestra la creación de un puente de entorno limitado principal en respuesta al evento dominitialize distribuido desde el fotograma secundario:

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

El siguiente documento child.html muestra cómo el contenido secundario puede acceder al puente de entorno limitado principal:

<html> 
    <head> 
        <script> 
            document.write(window.parentSandboxBridge.testProperty); 
        </script>   
    </head>   
    <body></body> 
</html>

Para detectar el evento dominitialize en un objeto window secundario, en lugar de un objeto frame, se debe añadir el detector al nuevo objeto secundario window creado por la función window.open() :

var childWindow = window.open(); 
childWindow.addEventListener("dominitialize", engageBridge()); 
childWindow.document.location = "http://www.example.com/air/child.html";

En este caso, no hay modo de asignar el contenido de aplicación en un entorno limitado que no pertenece a la aplicación. Esta técnica solo es útil cuando se carga child.html desde fuera del directorio de la aplicación. Aún se puede asignar el contenido de aplicación del objeto window a un entorno limitado que no pertenece a la aplicación, pero primero se debe cargar una página intermedia que utiliza fotogramas para cargar el documento secundario y asignarla al entorno limitado deseado.

Si se utiliza la función createRootWindow() de la clase HTMLLoader para crear una ventana, la nueva ventana no es un elemento secundario del documento desde donde se llama createRootWindow() . Por consiguiente, no se puede crear un puente de entorno limitado desde la ventana llamada al contenido que no pertenece a la aplicación cargado en la nueva ventana. En cambio, se debe cargar una página intermedia en la nueva ventana que utiliza fotogramas para cargar el documento secundario. Entonces se puede establecer el puente desde el documento principal de la nueva ventana al documento secundario cargado en el fotograma.