Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using annotations to control accessibility of java object in rhino #1792

Open
821938089 opened this issue Jan 7, 2025 · 3 comments
Open

Comments

@821938089
Copy link

Add three new annotations (tentative names):
@RhinoRestricted
@RhinoPublic
@RhinoPrivate

Usage:

  1. black list mode:
    Methods and fields and constructors marked with the RhinoPrivate annotation are not accessible in Rhino.
public class MyObject {

  String field1 = "field1";
  @RhinoPrivate
  String field2 = "field2";

  public String method1() {
    return "method1";
  }

  @RhinoPrivate
  public String method2() {
    return "method2";
  }

}
  1. white list mode
    All methods and fields and constructors of a class marked with the RhinoRestricted annotation cannot be accessed within Rhino unless marked RhinoPublic.
@RhinoRestricted
public class MyObject {

  @RhinoPublic
  String field1 = "field1";
  String field2 = "field2";

  @RhinoPublic
  public String method1() {
    return "method1";
  }

  public String method2() {
    return "method2";
  }

}
@rPraml
Copy link
Contributor

rPraml commented Jan 17, 2025

Hello @821938089

is the intention, that you want to execute code from (untrusted) user inputs and you want to try to add security with these annotations?
If so, you should read #861 #1045 and my advice is not to execute untrusted js code in a trusted JVM.
There are several ways to abuse the JVM: Locate all the memory, write never ending regexps or even escape the sandbox....

@821938089
Copy link
Author

Not for the sake of security, I'm using Rhino on Android and the app is written in Kotlin.
I have an object which can be accessed both in the app and in the script, but this object has some methods and fields which are only for the app to use, it belongs to the internal private API of the app and it should not be used in the script.

@rPraml
Copy link
Contributor

rPraml commented Jan 18, 2025

Thanks for providing a use case.

I took a look at the existing code. Every java object is wrapped by WrapperFactory in a NativeJavaObject
This does some reflection here
https://github.com/mozilla/rhino/blob/master/rhino/src/main/java/org/mozilla/javascript/NativeJavaObject.java#L57
and here
https://github.com/mozilla/rhino/blob/master/rhino/src/main/java/org/mozilla/javascript/JavaMembers.java#L804
where Rhino tries to honor java access restrictions

I see the following possibilities you can do now:

  • use java restrictions (package private methods, classes, module-info) and don't expose internal API.
  • Write your own WrapperFactory and create proxy/delegate objects, that hides internal API
  • Write good documentation and advice the user, not to use public methods from the internal API

Of course, it would be possible to add some checks for @RhinoPublic annotations in JavaMembers.discoverAccessibleMethods/getAccessibleFields, but that seems a bit strange to me, because if the API is reachable from java, why shoudn't I use it in rhino. (and to be honest, we try to add "security" here)

Maybe, it would also be also possible to enforce the static type here - so if you have public class MyImpl implements MyApi and you pass MyApi to lookupClass - it will see only the methods (but no fields!) of MyApi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants