----- Mail original ----- > De: "Peter Levart" <peter.lev...@gmail.com> > À: "Remi Forax" <fo...@univ-mlv.fr>, "Da Vinci Machine Project" > <mlvm-dev@openjdk.java.net> > Cc: "jochen Theodorou" <blackd...@gmx.org> > Envoyé: Jeudi 2 Juin 2016 10:26:48 > Objet: Re: proxy an interface and call a default method > > > > On 05/27/2016 01:40 PM, Remi Forax wrote: > > I don't see the issue if the lookup object represent the proxy class itself > > restricted to only access to public methods. > > > > Rémi > > I think there could be security issues. For example, let there be an > interface like: > > public interface Resource { > InputStream openStream() throws IOException; > > default byte[] getContent() throws IOException { > try (InputStream is = openStream()) { > return is.readAllBytes(); > } > } > } > > Then there might be an implementation that overrides both methods, like: > > public class SecuredResource implements Resource { > > @CallerSensitive > @Override > public InputStream openStream() throws IOException { > checkPermission(Reflection.getCallerClass()); > return openStreamImpl(); > } > > @CallerSensitive > @Override > public byte[] getContent() throws IOException { > checkPermission(Reflection.getCallerClass()); > try (InputStream is = openStreamImpl()) { > return is.readAllBytes(); > } > } > > private InputStream openStreamImpl() throws IOException { ... > ... > } > > > If Proxy API allowed access to a MH(invokespecial Resource::getContent), > then one could abuse such MH to circumvent access check in an instance > of SecuredResource by making it appear it was invoked from the Resource > class. > > I think that bytecode verifier does not allow such things and > SecuredResource can be considered perfectly safe in this respect.
I dont think this code is safe, without any proxy, you can create a MethodHandle with findvirtual() on Resource::getContent and bypass the check on @CallerSensitive. I'm not a security guy, but IMO, you can not annotate an overridden method with @CallerSensitive without creating a security hole. > > The solution could be for Proxy API to provide a MH that was already > bound to the Proxy instance. Such pre-bound MH could not be abused then. independently of any security issue, it may be a good idea but doing a partial evaluation on a MH is not cheap. > > Regards, Peter Rémi > > > > > ----- Mail original ----- > >> De: "Peter Levart" <peter.lev...@gmail.com> > >> À: "Da Vinci Machine Project" <mlvm-dev@openjdk.java.net>, "jochen > >> Theodorou" <blackd...@gmx.org> > >> Envoyé: Vendredi 27 Mai 2016 12:50:34 > >> Objet: Re: proxy an interface and call a default method > >> > >> Hi, > >> > >> I think the main problem here is that by providing the InvocationHandler > >> with a Lookup that could provide "invokespecial" MHs for the proxy > >> interface(s) could be abused. Anyone can create a Proxy for any public > >> interface and supply its own InvocationHandler which could be used to > >> "steal" such Lookup object. > >> > >> There would have to be a way to restrict calling interface "super" > >> methods from InvocationHandler *INSTANCES* that are bound to particular > >> Proxy instances. > >> > >> Hm... > >> > >> Regards, Peter > >> > >> On 05/26/2016 08:20 AM, Jochen Theodorou wrote: > >>> Hi all, > >>> > >>> I am looking for a solution to the following problem... I have an > >>> interface and an object that is supposed to serve as implementation, > >>> but does not implement the interface. n methods of the interface will > >>> be redirected to the object, but in case of default methods I would > >>> like to have the implementation provided by the interface. I am > >>> looking especially for a solution without me generating classes at > >>> runtime by hand. > >>> > >>> Now there are several problems... I seem not to be able to invoke a > >>> default method by reflection. By MethodHandles I did something like this: > >>> > >>>> MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, > >>>> int.class). > >>>> newInstance(interfaceClass, MethodHandles.Lookup.PRIVATE). > >>>> unreflectSpecial(method, interfaceClass). > >>>> bindTo(receiver); > >>> where receiver is a dynamic proxy, method the Method of the default > >>> method, interfaceClass the Class of the interface with the default > >>> method. > >>> > >>> But I am calling a private constructor here, which is bad, plus the > >>> above procedure does no longer work on JDK9. > >>> > >>> So what am I supposed to do? change from a proxy to runtime generated > >>> classes and hope the best for classloaders and modules not getting in > >>> my way? > >>> > >>> bye Jochen > >>> _______________________________________________ > >>> mlvm-dev mailing list > >>> mlvm-dev@openjdk.java.net > >>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > >> _______________________________________________ > >> mlvm-dev mailing list > >> mlvm-dev@openjdk.java.net > >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > >> > > _______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev