cordova-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Erik Jan de Wit <ede...@redhat.com>
Subject Re: Android Plugin API
Date Thu, 10 Jul 2014 11:48:58 GMT
Hi all,

Created an plugin that does this: https://github.com/edewit/aerogear-reflect-cordova the repository
also includes a example plugin that uses this. Also have a blog describing this a bit more
http://blog.nerdin.ch/2014/07/improved-cordova-android-plugin-api.html

Cheers,
	Erik Jan

On 2 Jun,2014, at 4:20 , Terence M. Bandoian <terence@tmbsw.com> wrote:

> It does get complicated in a hurry. Using the technique in the Google Maps plugin:
> 
> - getDeclaredMethod is documented to NOT return inherited methods which limits exposure
> - the signature passed to getDeclaredMethod also limits exposure
> - annotations, as Andrew suggested, could further limit exposure
> 
> - getDeclaredMethod is documented to return private methods which for me raises questions
> - setAccessible(true) suppresses normal access checking which also raises questions
> 
> - invoke throws InvocationTargetException so exceptions thrown by the invoked method
could be publicized
> - invoke applies overriding which is probably a wash
> - invoke returns an object which would have to be handled correctly
> 
> Quite a bit to consider.
> 
> -Terence Bandoian
> 
> 
> On 5/29/2014 11:44 PM, Joe Bowser wrote:
>> On Thu, May 29, 2014 at 9:26 PM, Terence M. Bandoian <terence@tmbsw.com> wrote:
>>> Please correct me if I'm wrong but, as I understand it, the vulnerability
>>> stems from injecting a Java object into the WebView which, in API levels 16
>>> and below, exposed all of the public methods of the object (small 'o')
>>> including the methods inherited from the Object class.
>>> 
>> Yes, you are correct in this case.  You can basically use the object
>> methods to reflect into whatever you want.  Once you have a single
>> class exposed in this manner, you can then reflect into it, and
>> basically you're done.  The reason we don't use reflection is that
>> it's very easy to reflect into things you're not supposed to be in.
>> IMO, It wouldn't be hard to do this if we exposed plugins in the same
>> way.  Right now this is an Android Vulnerability, but if we start
>> using reflection for plugins, we could very quickly end up making a
>> similar Cordova exploit if we're not careful.
>> 
>> This is also why we use the prompt bridge on API levels below 17.
>> 
>>> 
>>> 
>>> On 5/28/2014 9:54 AM, Joe Bowser wrote:
>>>> In case anyone is curious, here's why we minimize reflection:
>>>> 
>>>> 
>>>> https://labs.mwrinfosecurity.com/blog/2013/09/24/webview-addjavascriptinterface-remote-code-execution/
>>>> 
>>>> On Wed, May 28, 2014 at 7:33 AM, Andrew Grieve <agrieve@chromium.org>
>>>> wrote:
>>>>> Another reasonable approach would be to use a Map<String, Runnable>,
but
>>>>> that can be implemented on top of what is currently exposed. I'm quite
>>>>> wary
>>>>> of Reflection as well.
>>>>> 
>>>>> 
>>>>> On Wed, May 28, 2014 at 10:06 AM, Joe Bowser <bowserj@gmail.com>
wrote:
>>>>> 
>>>>>> The execute command exists for security reasons.  We don't want any
>>>>>> methods other than execute exposed to Javascript.  I also prefer
this
>>>>>> approach because it is less prone to less catastrophic bugs than
using
>>>>>> Java reflection.  We try and only use reflection when we have to.
>>>>>> 
>>>>>> On Wed, May 28, 2014 at 5:50 AM, Erik Jan de Wit <edewit@redhat.com>
>>>>>> wrote:
>>>>>>> Hi,
>>>>>>> 
>>>>>>> When one is writing a plugin for android ATM the api that you
have to
>>>>>> implement has a execute method that has the action as a string:
>>>>>>> @Override
>>>>>>>      public boolean execute(String action, JSONArray args,
>>>>>> CallbackContext callbackContext) throws JSONException {
>>>>>>>          if ("beep".equals(action)) {
>>>>>>>              this.beep(args.getLong(0));
>>>>>>>              callbackContext.success();
>>>>>>>              return true;
>>>>>>>          }
>>>>>>>          return false;  // Returning false results in a
>>>>>>> "MethodNotFound"
>>>>>> error.
>>>>>>>      }
>>>>>>> When you have multiple actions this method gets very long, if
you
>>>>>> compare this with iOS here you don’t need a method like this you
could
>>>>>> ‘just’ implement the method directly:
>>>>>>> - (void)beep:(CDVInvokedUrlCommand*)command
>>>>>>>      {
>>>>>>>          CDVPluginResult* pluginResult =;
>>>>>>>          NSString* myarg =mmand.arguments objectAtIndex:0];
>>>>>>> 
>>>>>>>          if (myarg !=) {
>>>>>>>              pluginResult �VPluginResult
>>>>>> resultWithStatus:CDVCommandStatus_OK];
>>>>>>>          } else {
>>>>>>>              pluginResult �VPluginResult
>>>>>> resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Arg was
>>>>>> null"];
>>>>>>>          }
>>>>>>>          [self.commandDelegate sendPluginResult:pluginResult
>>>>>> callbackId:command.callbackId];
>>>>>>>      }
>>>>>>> We could do the same thing for android if we use reflection,
making the
>>>>>> API more similar and removing all the string test by the user. What
do
>>>>>> you
>>>>>> think?
>>>>>>> Cheers,
>>>>>>>          Erik Jan


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message