Cette section décrit l’architecture de la sécurité HTML dans AIR, ainsi que l’utilisation d’iframes, d’images et du pont de sandbox pour configurer les applications HTML et sécuriser l’intégration de contenu HTML à des applications SWF.
Le moteur d’exécution applique des règles et fournit des mécanismes pour compenser des vulnérabilités de sécurité possibles dans HTML et JavaScript. Les mêmes règles s’appliquent que votre application soit rédigée principalement en JavaScript ou que vous chargiez le contenu HTML et JavaScript dans une application basée sur SWF. Les contenus du sandbox de l’application et du sandbox de sécurité hors application possèdent des privilèges différents. Lorsque vous chargez un contenu dans une iframe ou une image, le moteur d’exécution fournit un mécanisme
pont de sandbox
sécurisé qui permet au contenu de l’image ou de l’iframe de communiquer de façon sûre avec le contenu du sandbox de sécurité de l’application.
Le SDK d’AIR intègre trois classes de rendu du contenu HTML.
La classe HTMLLoader assure une intégration étroite entre le code JavaScript et les API d’AIR.
La classe StageWebView est une classe de rendu HTML et son intégration à l’application AIR hôte est extrêmement réduite. Le contenu chargé par la classe StageWebView n’est jamais placé dans le sandbox de sécurité de l’application et il lui est impossible d’accéder aux données ou d’appeler des fonctions dans l’application AIR hôte. Sur les plates-formes de poste de travail, la classe StageWebView fait appel au moteur HTML AIR intégré, basé sur Webkit, qui est également utilisé par la classe HTMLLoader. Sur les plates-formes mobiles, elle fait appel au contrôle HTML fourni par le système d’exploitation. Par conséquent, sur les plates-formes mobiles, la classe StageWebView est soumise aux mêmes considérations de sécurité et souffre des mêmes vulnérabilités que le navigateur Web du système.
La classe TextField peut afficher des chaînes de texte HTML. Il est impossible d’exécuter du code JavaScript, mais le texte peut inclure des liens et des images chargées en externe.
Pour plus d’informations, voir la section
Contournement des erreurs JavaScript liées à la sécurité
.
Aperçu de la configuration de vos applications à base d’HTML
Les images et iframes fournissent une structure adéquate pour l’organisation du contenu HTML dans AIR. Les images fournissent des moyens qui permettent à la fois de maintenir la persistance des données et pour travailler de façon sécurisée avec du contenu distant.
Comme HTML dans AIR conserve son organisation normale, basée sur des pages, l’environnement HTML est intégralement actualisé si l’image supérieure de votre contenu HTML « navigue » dans une page différente. Vous pouvez utiliser des images et des iframes pour maintenir la persistance des données dans AIR pratiquement de la même façon que vous le feriez pour une application Web qui s’exécuterait dans un navigateur. Définissez les principaux objets de votre application dans l’image supérieure et ils persisteront aussi longtemps que vous n’autoriserez pas l’image à naviguer dans une nouvelle page. Utilisez des images ou des iframes enfant pour charger et afficher des parties transitoires de l’application. Il existe plusieurs façons de maintenir la persistance des données, en plus des images ou bien à leur place. Par exemple, des cookies, des objets locaux partagés, l’emplacement de stockage des fichiers locaux, celui des fichiers chiffrés et celui des bases de données locales.
Comme HTML dans AIR conserve sa frontière normale et imprécise entre le code exécutable et les données, AIR place le contenu de l’image supérieure de l’environnement HTML dans le sandbox de l’application. Après l’événement
load
de la page, AIR restreint toutes les opérations, telles que
eval()
, susceptibles de convertir une chaîne de texte en un objet exécutable. Cette restriction est imposée même lorsqu’une application ne charge pas du contenu distant. Pour que du contenu HTML distant puissent exécuter ces opérations restreintes, vous devez utiliser des images ou des iframes pour placer le contenu dans un sandbox hors application. (L’exécution de contenu dans une image enfant affectée à un sandbox peut s’avérer nécessaire lorsque vous utilisez des structures d’application JavaScript qui reposent sur la fonction
eval()
.) Pour un répertoire complet des restrictions relatives à JavaScript dans le sandbox de l’application, voir la section
Restrictions relatives au code pour un contenu dans des sandbox différents
.
Comme HTML dans AIR conserve sa capacité à charger du contenu distant et possiblement non sécurisé, AIR applique une politique de « même origine » qui empêche le contenu d’un domaine d’interagir avec celui de l’autre. Pour permettre une interaction entre contenu de l’application et contenu d’un autre domaine, vous pouvez configurer un pont qui servira d’interface entre une image parent et une image enfant.
Configuration d’un rapport de sandbox parent-enfant
AIR ajoute les attributs
sandboxRoot
et
documentRoot
aux éléments image et iframe de HTML. Ces attributs vous permettent de traiter le contenu de l’application comme s’il provenait d’un autre domaine :
Attribut
|
Description
|
sandboxRoot
|
L’URL à utiliser pour déterminer le sandbox et le domaine dans lesquels placer le contenu de l’image. Les modèles d’URL
file:
,
http:
ou
https:
doivent être utilisés.
|
documentRoot
|
L’URL à partir de laquelle il faut charger le contenu de l’image. Les modèles d’URL
app:
,
http:
ou
app-storage:
doivent être utilisés.
|
L’exemple ci-dessous mappe le contenu installé dans le sous-répertoire du sandbox de l’application qui doit s’exécuter dans le sandbox distant et le domaine www.example.com :
<iframe
src="ui.html"
sandboxRoot="http://www.example.com/local/"
documentRoot="app:/sandbox/">
</iframe>
Configuration d’un pont entre images parent et enfant dans des sandbox ou des domaines différents
AIR ajoute les propriétés
childSandboxBridge
et
parentSandboxBridge
à l’objet
window
de toute image enfant. Ces propriétés vous permettent de définir des ponts qui serviront d’interfaces entre une image parent et une image enfant. Chaque pont ne va que dans une seule direction :
childSandboxBridge
: la propriété
childSandboxBridge
permet à l’image enfant de présenter une interface au contenu dans l’image parent. Pour présenter une interface, vous définissez la propriété
childSandbox
sur une fonction ou un objet dans l’image enfant. Vous pouvez alors accéder à l’objet ou à la fonction à partir du contenu dans l’image parent. L’exemple ci-dessous montre comment un script qui s’exécute dans une image enfant peut présenter un objet contenant une fonction ou une propriété à son parent :
var interface = {};
interface.calculatePrice = function(){
return .45 + 1.20;
}
interface.storeID = "abc"
window.childSandboxBridge = interface;
Si ce contenu enfant est dans une iframe affectée d’une
id
child
, vous pouvez accéder à l’interface à partir du contenu parent en lisant la propriété
childSandboxBridge
de l’image :
var childInterface = document.getElementById("child").childSandboxBridge;
air.trace(childInterface.calculatePrice()); //traces "1.65"
air.trace(childInterface.storeID)); //traces "abc"
parentSandboxBridge
: la propriété
parentSandboxBridge
permet à l’image parent de présenter une interface au contenu dans l’image enfant. Pour présenter une interface, vous définissez la propriété
parentSandbox
de l’image enfant sur une fonction ou un object dans l’image parent. Vous pouvez alors accéder à l’objet ou à la fonction à partir du contenu dans l’image enfant. L’exemple ci-dessous montre comment un script qui s’exécute dans l’image parent peut présenter un objet contenant une fonction save à un enfant :
var interface = {};
interface.save = function(text){
var saveFile = air.File("app-storage:/save.txt");
//write text to file
}
document.getElementById("child").parentSandboxBridge = interface;
Avec cette interface, le contenu de l’image enfant pourrait enregistrer du texte dans un fichier appelé save.txt. Toutefois, il ne pourrait avoir aucun autre accès au système de fichiers. En règle générale, le contenu de l’application devrait présenter l’interface la plus étroite possible aux autres sandbox. Le contenu enfant pourrait appeler la fonction save comme suit :
var textToSave = "A string.";
window.parentSandboxBridge.save(textToSave);
Si le contenu enfant tente de définir une propriété de l’objet
parentSandboxBridge
, le moteur d’exécution renvoie une exception SecurityError. Si le contenu parent tente de définir une propriété de l’objet
childSandboxBridge
, le moteur d’exécution renvoie une exception SecurityError.
Restrictions relatives au code pour un contenu dans des sandbox différents
Comme nous l’avons vu dans l’introduction à cette rubrique,
Sécurité HTML dans Adobe AIR
, le moteur d’exécution applique les règles et fournit des mécanismes pour compenser les vulnérabilités de sécurité possibles dans HTML et JavaScript. La présente rubrique répertorie ces restrictions. Si le code tente d’appeler ces interfaces de programmation réservées, le moteur d’exécution renvoie une erreur accompagnée du message « Violation des règles de sécurité dans le sandbox de sécurité de l’application par le moteur d’exécution d’Adobe AIR sur du code JavaScript ».
Pour plus d’informations, voir la section
Contournement des erreurs JavaScript liées à la sécurité
.
Restrictions relatives à l’utilisation de la fonction eval() de JavaScript et de techniques similaires
Pour le contenu HTML dans le sandbox de sécurité de l’application, il existe des limites dans l’utilisation des interfaces de programmation susceptibles de transformer dynamiquement les chaînes en code exécutable après le chargement de ce code (après que l’événement
onload
de l’élément
body
a été distribué et que l’exécution de la fonction du gestionnaire
onload
est terminée). Ceci empêche l’application d’injecter (et d’exécuter) du code par inadvertance à partir de sources non-applicatives, comme des domaines du réseau potentiellement non sécurisés.
Par exemple, si votre application utilise des données de chaîne à partir d’une source distante pour écrire dans la propriété innerHTML d’un élément DOM, la chaîne pourrait inclure du code exécutable (JavaScript) et susceptible d’exécuter des opérations non sécurisées. Toutefois, tant que le contenu est en cours de chargement, il n’y a pas de risque que des chaînes distantes soient insérées dans le DOM.
L’utilisation de la fonction
eval()
de JavaScript constitue une restriction. Dès que le code du sandbox de l’application est chargé et après le traitement du gestionnaire d’événement onload, vous ne pouvez utiliser la fonction
eval()
que dans certaines conditions. Les règles suivantes s’appliquent dans l’utilisation de la fonction
eval()
après
le chargement du code à partir du sandbox de sécurité de l’application :
-
Les expressions contenant des littéraux sont autorisées. Exemple :
eval("null");
eval("3 + .14");
eval("'foo'");
-
Les littéraux d’objet sont autorisés, comme dans les cas décrits ci-dessous :
{ prop1: val1, prop2: val2 }
-
Les littéraux d’objet de lecture et de définition (getter/setter) sont
interdits
comme dans les exemples ci-dessous :
{ get prop1() { ... }, set prop1(v) { ... } }
-
Les littéraux de tableau sont autorisés, comme dans les cas décrits ci-dessous :
[ val1, val2, val3 ]
-
Les expressions impliquant des lectures de propriété sont
interdites
comme dans ce qui suit :
a.b.c
-
Le lancement de fonctions est
interdit
.
-
Les définitions de fonctions sont
interdites
.
-
Le paramétrage de toute propriété est
interdit
.
-
Les littéraux de fonctions sont
interdits
.
Toutefois, au cours du chargement du code, avant l’événement
onload
et au cours de l’exécution de la fonction du gestionnaire d’événement
onload
, ces restrictions ne s’appliquent pas au contenu du sandbox de sécurité de l’application.
Par exemple, après le chargement du code, l’exécution du code ci-dessous dans le moteur d’exécution renvoie une exception.
eval("alert(44)");
eval("myFunction(44)");
eval("NativeApplication.applicationID");
Un code généré dynamiquement, comme celui qui est produit par l’appel de la fonction
eval()
, présenterait un risque pour la sécurité s’il était autorisé au sein du sandbox de l’application. Par exemple, une application peut exécuter par inadvertance une chaîne chargée à partir d’un domaine de réseau et celle-ci peut contenir du code malveillant. Par exemple, il peut s’agir de code conçu pour la suppression ou la modification de fichiers dans l’ordinateur de l’utilisateur. Ou bien encore de code qui renvoie à un domaine de réseau non approuvé une copie du contenu d’un fichier local.
Vous trouverez ci-dessous des façons de générer du code dynamique :
-
Appel de la fonction
eval()
.
-
Utilisation des propriétés
innerHTML
ou des fonctions DOM pour insérer des balises de script qui chargent un script hors du répertoire de l’application.
-
Utilisation des propriétés
innerHTML
ou des fonctions DOM pour insérer des balises de script qui possèdent du code incorporé (plutôt que de charger un script au moyen de l’attribut
src
).
-
Paramétrage de l’attribut
src
pour qu’une balise
script
charge un fichier JavaScript qui est hors du répertoire de l’application.
-
Utilisation du modèle d’URL de
JavaScript
comme dans (
href="javascript:alert('Test')"
).
-
Utilisation de la fonction
setInterval()
ou
setTimout()
, où le premier paramètre (qui définit la fonction pour qu’elle s’exécute de façon asynchrone) est une chaîne (à évaluer) plutôt qu’un nom de fonction (comme dans
setTimeout('x = 4', 1000)
).
-
Appel de
document.write()
ou de
document.writeln()
.
Le code dans le sandbox de sécurité de l’application ne peut utiliser ces méthodes au cours du chargement du contenu.
Ces restrictions n’empêchent
pas
l’utilisation d’
eval()
avec des littéraux d’objet JSON. Ceci permet au contenu de votre application de travailler avec la bibliothèque JavaScript de JSON. Il vous est néanmoins interdit d’utiliser du code JSON surchargé (avec des gestionnaires d’événement).
Pour d’autres structures Ajax et bibliothèques de code JavaScript, assurez-vous que le code de la structure ou de la bibliothèque fonctionne sur du code généré dynamiquement, dans le cadre de ces restrictions. Si ce n’est pas le cas, placez tout contenu qui utilise la structure ou la bibliothèque dans un sandbox de sécurité hors application. Pour plus d’informations, voir
Restrictions associées au contenu JavaScript dans AIR
et
Programmation entre contenu d’application et contenu hors application
. Adobe maintient un répertoire de structures Ajax, reconnues pour leur prise en charge du sandbox de sécurité de l’application, à l’adresse
http://www.adobe.com/products/air/develop/ajax/features/
.
Contrairement au contenu du sandbox de sécurité de l’application, celui de JavaScript dans un sandbox de sécurité hors application
peut
à tout moment appeler la fonction
eval()
pour exécuter dynamiquement le code généré.
Restrictions relatives à l’accès aux interfaces de programmation AIR (pour des sandbox hors application)
Le code JavaScript dans un sandbox hors application n’a pas accès à l’objet
window.runtime
et, de ce fait, il ne peut pas exécuter d’interfaces de programmation AIR. Si un contenu, dans un sandbox de sécurité hors application, appelle le code ci-dessous, l’application renvoie une exception TypeError.
try {
window.runtime.flash.system.NativeApplication.nativeApplication.exit();
}
catch (e)
{
alert(e);
}
Le type d’exception est TypeError (valeur non définie) parce que le contenu du sandbox hors application ne reconnaît pas l’objet
window.runtime
de sorte qu’il est considéré comme une valeur non définie.
Vous pouvez présenter les fonctionnalités du moteur d’exécution dans un sandbox hors application à l’aide d’un pont de script. Pour plus d’informations, voir
Programmation entre contenu d’application et contenu hors application
.
Restrictions relatives à l’utilisation des appels XMLHttpRequest
Le contenu HTML du sandbox de sécurité de l’application utilise des méthodes XMLHttpRequest pour charger des données à partir d’emplacements hors du sandbox de l’application au cours du chargement du contenu HTML et de l’exécution de l’événement
onLoad
.
Par défaut, un contenu HTML dans des sandbox de sécurité hors application n’est pas autorisé à utiliser l’objet XMLHttpRequest de JavaScript pour charger des données à partir des domaines autres que le domaine qui appelle la requête. Une balise
image
ou
iframe
peut contenir un attribut
allowcrosscomainxhr
. La définition de cet attribut sur toute valeur non nulle permet au contenu de l’image ou de l’iframe d’utiliser l’objet XMLHttpRequest de JavaScript pour charger les données à partir de domaines autres que celui du code qui appelle la requête.
<iframe id="UI"
src="http://example.com/ui.html"
sandboxRoot="http://example.com/"
allowcrossDomainxhr="true"
documentRoot="app:/">
</iframe>
Pour plus d’informations, voir
Programmation entre contenus de différents domaines
.
Restrictions relatives au chargement d’éléments de CSS, d’image, d’iframe et d’img (pour un contenu dans des sandbox hors application)
Un contenu HTML dans un sandbox de sécurité distant (réseau) ne peut charger que du contenu CSS,
image
,
iframe
et
img
à partir de sandbox distants (à partir d’URL du réseau).
Un contenu HTML dans un sandbox local avec système de fichiers, local avec réseau ou approuvé localement ne peut charger que du contenu CSS, image, iframe et
img
à partir de sandbox locaux (mais pas à partir de sandbox d’application ou distants).
Restrictions relatives à l’appel de la méthode window.open() de JavaScript
Si une fenêtre créée par un appel à la méthode
window.open()
de JavaScript affiche un contenu à partir d’un sandbox de sécurité hors application, le titre de la fenêtre commence par celui de la fenêtre principale (de lancement), suivi du caractère deux points (:). Il n’est pas possible d’utiliser du code pour retirer cette partie du titre de l’écran.
Le contenu d’un sandbox de sécurité hors application ne peut réussir un appel à la méthode
window.open()
de JavaScript que s’il répond à un événement déclenché par la souris ou le clavier de l’utilisateur. Cette condition permet d’éviter qu’un contenu hors application ne crée des fenêtres qui pourraient être utilisées de façon trompeuse, par exemple pour des attaques d’hameçonnage. En outre, le gestionnaire d’événement pour l’événement de la souris ou du clavier ne peut pas paramétrer la méthode
window.open()
pour qu’elle s’exécute au bout d’un certain temps, par exemple en appelant la fonction
setTimeout()
.
Le contenu d’un sandbox distant (réseau) ne peut utiliser la méthode
window.open()
que pour ouvrir le contenu dans un sandbox de réseau distant. Il ne peut pas utiliser cette méthode pour ouvrir du contenu à partir de l’application ou d’un sandbox local.
Un contenu de sandbox local avec système de fichiers, sandbox local avec réseau ou sandbox approuvé localement (voir
Sandbox de sécurité
) ne fait appel à la méthode
window.open()
que pour ouvrir un contenu dans un sandbox local. Il ne peut pas utiliser cette méthode pour ouvrir du contenu à partir de l’application ou d’un sandbox distant.
Erreurs lors de l’appel de code interdit
Si vous appelez du code interdit d’exécution dans un sandbox en raison de ces restrictions liées à la sécurité, le moteur d’exécution distribue une erreur JavaScript : « Violation des règles de sécurité dans le sandbox de sécurité de l’application par le moteur d’exécution d’Adobe AIR sur du code JavaScript ».
Pour plus d’informations, voir la section
Contournement des erreurs JavaScript liées à la sécurité
.
Protection du sandbox lors du chargement de contenu HTML depuis une chaîne
La méthode
loadString()
de la classe HTMLLoader vous permet de créer du contenu HTML au moment de l’exécution. Toutefois, les données utilisées comme contenu HTML peuvent être corrompues lorsqu’elles sont chargées à partir d’une source Internet non sécurisée. De ce fait, par défaut, le contenu HTML créé à l’aide de la méthode
loadString()
n’est pas placé dans le sandbox de l’application et n’a pas accès aux API AIR. Vous pouvez cependant définir la propriété
placeLoadStringContentInApplicationSandbox
d’un objet HTMLLoader sur true pour placer le contenu HTML créé avec la méthode
loadString()
dans le sandbox de l’application. Pour plus d’informations, voir la section
Chargement de contenu HTML depuis une chaîne
.
|
|
|