HTML Viewer - script injection, app.Execute

469 views
Skip to first unread message

Aerik Sylvan

unread,
Dec 2, 2014, 6:56:02 PM12/2/14
to androi...@googlegroups.com
I had thought it would be trivial to inject the "app.js" file into a remote web page and thus create bidirectional communication with a remote page... but I haven't been able to do it.  I can execute arbitrary js on pages using webview.Execute, and I can add scripts to those pages (testing using other scripts) but not the app.js file... (is it really a file?)

Anybody else trying to do anything similar have any luck?

Thanks,
Aerik

Steve Garman

unread,
Dec 2, 2014, 7:10:48 PM12/2/14
to androi...@googlegroups.com
My understanding is that this is no longer permitted on remote sites since v1.11

Dave Smart

unread,
Dec 5, 2014, 3:58:52 AM12/5/14
to androi...@googlegroups.com
Hi Guys,

If you want to enable remote pages to call webview.Execute() then you will need to add the "AllowRemote" option when you create the WebView control.

This functionality is available in the current private beta 1.15 which should be hopefully released publicly in the next day or two.

Note: For security reasons, when using this option, it is VERY important to make sure you do not allow users of the WebView to browse onto any web pages that are not controlled by you.

Regards
David

Aerik Sylvan

unread,
Dec 9, 2014, 7:27:12 PM12/9/14
to androi...@googlegroups.com
I must still be doing something wrong.  Here's my test DroidScript code:


//Called when application is started.
function OnStart()
{
   
//Create a layout with objects vertically centered.
    lay
= app.CreateLayout( "linear", "VCenter,FillXY" );    


//Create Dynamic button.
 btnDynamic
= app.CreateButton( "Dynamic" );
 btnDynamic
.SetOnTouch( btnDynamic_OnTouch );
 lay
.AddChild( btnDynamic );
 
 
//Create Remote button.
 btnRemote
= app.CreateButton( "Remote" );
 btnRemote
.SetOnTouch( btnRemote_OnTouch );
 lay
.AddChild( btnRemote );


   
//Create a web control.
    web
= app.CreateWebView( 1, .5, "AllowZoom,AllowRemote" );
    web
.SetOnProgress( web_OnProgess );
    lay
.AddChild( web );
   
   
//Add layout to app.    
    app
.AddLayout( lay );
   
Test2();
}


function btnDynamic_OnTouch()
{
   
Test();
}
function btnRemote_OnTouch()
{
   
Test2();
}


function notify(){
   
var notify1 = app.CreateNotification();
    notify1
.SetMessage( "You have a notification!", "My Title", "My Details" );
    notify1
.SetLights( "#00ffff", 500, 500 );
    notify1
.Notify();
}


function Test(){
   
var html = "<html><head>";
    html
+= "<meta name=viewport content=width=device-width>";
    html
+= '<script src="file:///android_asset/app.js"></script>';
    html
+= "</head><body>Hello Dynamic World!<br>";
    html
+= "<script>app.Execute('notify()');</script>";
    html
+= "</body></html>";
    web
.LoadHtml( html, "file:///Sys/" );
   
//notify();y
}


function Test2(){
        web
.LoadUrl( "http:///aerik.com/temp/test.htm" );
}


//Show page load progress.
function web_OnProgess( progress )
{
   
if(progress == 100){


   
}
}

And here is my remote web page where I try two different things to fire the notify function and neither works

<html><head>
<script src="file:///android_asset/app.js"></script>
</head><body>Remote page<br>
<script>app.Execute('notify()');</script>
<script>notify();</script>
</body></html>

Please help!
Thanks,
Aerii

Steve Garman

unread,
Dec 9, 2014, 11:24:25 PM12/9/14
to androi...@googlegroups.com
Hi Aerik,
Looking at your post in the early hours of the morning through half-closed eyes, it looks like your remote page is defining a couple of scripts but not running them.

Should you be using something like this?

http://www.w3schools.com/jsref/event_onload.asp

Aerik Sylvan

unread,
Dec 10, 2014, 12:51:37 PM12/10/14
to androi...@googlegroups.com
New remote page:

<html><head>
<script src="file:///android_asset/app.js"></script>
<script>
window.onload=function(){
alert("just making sure this is running");
prompt(null,"app.Execute('notify();')");
app.Execute('notify()');
}
</script>
</head>
<body>Remote page v2<br>
</body>
</html>


I tried various combinations of prompt, just calling "notify()", etc.  No luck :-(

Chris Hopkin

unread,
Dec 11, 2014, 5:20:12 AM12/11/14
to androi...@googlegroups.com
Hi Aerik

I've tried this and had the same problem. It seems there is a security issue here, the WebView (Chrome) is not allowed to load the app.js local resource from a remote site. Therefore any calls to app.Execute won't work.

If you really need this functionality from a remote site, then instead of including app.js, add the following JavaScript function to your remote page:

function Execute(func)
{
   prompt
( "@", "App.Execute(" + func );
}

Then call Execute instead of app.Execute, e.g.

Execute("notify()");

I just want to reiterate Dave's earlier security note: For security reasons, when using this option, it is VERY important to make sure you do not allow users of the WebView to browse onto any web pages that are not controlled by you.

Thanks

Chris

Steve Garman

unread,
Dec 11, 2014, 8:40:06 AM12/11/14
to androi...@googlegroups.com
Hi Aerik,

and further to Chris' post, I'd like to point out (in case you hadn't noticed)  that in this case, App is spelled with a capital A

Aerik Sylvan

unread,
Dec 11, 2014, 1:48:58 PM12/11/14
to androi...@googlegroups.com
Okay, that works, thanks!... a few observations / questions:

What is the "App" (capital A) object?  It seems to be a valid javascript object, but has no properties (at least in my simple object inspector code).  Is it some hard coded thing?  I tried to do 

var myapp = App;
App = null;

to kind of alias the App object, but it doesn't work (I was thinking it would be a nice way to enhance security).

Also, it is interesting to note that this code 

prompt( "@", "App.Execute(" + func );

is missing the closing parenthesis for the App.Execute function call, but it still works.  As a matter of fact, it breaks if I add the closing parenthesis .

Let me explain one of my use cases:  I want to use script injection to interact with a third party website.  This is doable with the "prompt..." code, but not terribly secure, as pointed out.  I had hoped to address that by aliasing the "app" or "App" object.  Realistically, my little app will not be popular enough to get anyones attention and no one will take advantage of the security hole, but it was a  nice thought.

Thanks and Best Regards,
Aerik



Reply all
Reply to author
Forward
0 new messages