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 <tere...@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 <tere...@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 <agri...@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 <bows...@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 <ede...@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