Minor thoughts (Re: [External] : Re: JEP draft: Prepare to Restrict The Use of JNI
Rony G. Flatscher
Rony.Flatscher at wu.ac.at
Thu Aug 31 13:03:28 UTC 2023
Hi Ron,
thank you for your comments. One thing, please do not take any of my comments personal if I try to
point out something that I regard to be possibly oversights and shortcomings, my comments are meant
constructively.
It is clear that you are an expert and have been working in this area intensively. However, it may
be the case that you and your peers are focused on pure Java applications that get their own
tailored JRE exploiting modules with jlink and or tooling that does all the "dirty" work for you. In
such a world it may be the case that inventing new switches is not regarded to be a problem, if the
"user" is the application developer from whom you expect to have the same knowledge, overview and
commandment of all switches and dependencies that each new version of Java brings along. (I doubt
that that can be really expected.)
There are quite many Java deployments that are important for non-Java applications taking advantage
of the JRE infrastructure, taking advantage of the platform independent functionality of the JRE
classes and optionally add additional Java class libraries like jsoup. In such a world the intimate
knowledge of the latest Java version and the module system is not relevant. :) What counts is what
public Java classes can be loaded and exploited.
Add to that the fact that in the real world applications may use totally outdated versions of Java
as long as possible. I know of deployments of Java 6 and 7 still in use which is the reason why I
still maintain a Java bridge with the Java 6 baseline, believe it or not.
In such a world updating to a new version of Java that starts to warn and potentially terrify the
end-users that something about using Java has become dangerous all of a sudden is counterproductive
to say the least. End-users, application users lack the understanding, they have not followed
discussions like this one, have no knowledge of JEPs, they are usually helpless then, but feeling
more and more insecure about using Java at all.
Expecting - what is easy for guys like you (or us) - to add just another "easy flag" that removes
such terrifying messages is just not realistic, they are not able to do so, believe it or not. They
get scared and for them it is obviously Java's fault that it gets all of a sudden dangerous,
insecure as even Java itself warns about it!
Take the following ooRexx program as an example (yes, it uses JRE, any actual version of Java will
do, e.g. Java 8, 17, 22, ...):
say .java.lang.System~getProperty("java.version")
::requires "BSF.CLS" -- get the ooRexx-Java bridge
The output of running the above program may be something like (depending on the JREs in use):
1.8.0_362
17.0.6
18.0.1.1
Any of my students is able to create such programs that exploit Java classes in the current JRE
(including exploiting JavaFX by the way). Change JAVA_HOME and you change the JRE in use and the
program still works.
If running such a program on a new Java version all of a sudden yields a security warning out of the
blue telling them that what they do is dangerous, unsecure etc. will scare them to death and
eventually scare them away from Java, making them turn to other programming runtime environments
that do not scare them.
These students BTW are business administration students, so please do not expect that anything what
is easy for this group is easy for them at all, rather expect that what is easy for this group is
simply impossible for them!
On 30.08.2023 20:08, Ron Pressler wrote:
>> On 30 Aug 2023, at 17:21, Rony G. Flatscher<Rony.Flatscher at wu.ac.at> wrote:
> Hi.
>
>> The road to hell is paved with good intentions ...
> Every Java library requires adding a token to the command line; what we’re talking about here is adding another one for the small minority of libraries that use native code.
>
> In fact, the command line work that’s required has barely changed. If you’re using the classpath, then most applications typically mention each and every JAR individually; if any of them requires native access you only need to add --enable-native-access=ALL-UNNAMED. If, on the other hand, you’re using the module path, then normally you’re only providing a single directory, and now you’ll also have to list every module that requires native access, and it’s still *fewer* tokens on the command line than Java applications put there ten years ago.
>
> So we can talk about the merits of this minor inconvenience, but merited or not — it’s not something that can lead to any hell.
This depends on the "user" who uses/exploits Java without the expert knowledge you have. What is
easy for you (or us) may be impossible, cumbersome for others. The message these users get is more
than scary if Java starts to warn (or even aborts with an error) from using Java!
>> A few minor thoughts:
>> • Java needs JNI itself: so how can the "user" be warned from using Java as this is considered to be potentially dangerous by the Java developers themselves?
>> (And what can be done to warn a "user" from using operating system features? Should Java warn the "user" that potentially dangerous native code gets employed by Java whenever the operating system gets accessed for one reason or another?)
> I’m afraid there’s been some confusion about who the user is. The user we’re referring to in the JEP is the application author. The application’s end user need not add any flags, see any flags, or even be aware they’re running an application written in Java. All the flags we’re discussing are internal to the application, and can be collected in the usual way in configuration @files or with jlink. The application’s author has a choice of whether or not to use a library that requires certain special powers, in this case — running native code.
>
> The application’s author chooses what launcher to use, and that launcher can grant native access privileges to any library that the application author chooses. If someone uses the launcher that comes with the JDK it is preconfigured with such permissions for the JDK’s modules.
In my use case the "application author" are students who use the current JRE and have no clues about
the Java module system, the latest JEPs and the latest and greatest features of OpenJDK/Java let
alone the latest invented switches.
If the "user" is the "application author" who is one who creates a pure Java application and
controls its setup, the JRE to use, why is it then necessary to warn Java "application authors"
about something that may not be even true, that the JNI module in use would be dangerous and/or a
security risk?
However, if it is intended to make users of JREs (standard ones or jlink'ed ones) aware that modules
use JNI without reporting that usage by warning them, then it would be fine as long as no warning
occurs when modules report the usage of JNI modules in their module-info. This scenario is then a
constructive one, issuing the warnings only, if JNI usage is not communicated explicitly.
>> • Possible dangerous or fatal errors in native code do not mean that these errors exist in reality at all, i.e. in deployed JNI modules that get tested and deployed.
>> This is a bit along the line that a knife can be dangerous as it can be used to kill a person, yet, knives in the world do not get used to kill people: the good intent is to make the world safer, so we prohibit knives or only allow their use, if the user keys in the flag "--knives-can-kill-persons" and then the storage box opens to release the knife such that one can finally cut the steak.
>> (Just because something can be used dangerously does not mean that it will be used that way and do harm; any acknowledgement of potential danger does not make the danger go away nor does the warning help to circumvent the potential danger.)
> Sure, which is why we’re not discouraging the use of native code, just asking the application’s author to acknowledge that they know there are knives in play.
Why is that important? For whom is this important?
People know that one can kill with a knife, why would you want to warn everyone forcefully that
knives can kill people, if the normal, expected usage of a knife is for cutting meat and vegetables?
(If an "application author" uses modules from sources she or he does not trust, then such a human
would be expected to check thoroughly such modules, if they should be used nevertheless, wouldn't
she or he?)
>> • Just pointing out that erroneously implemented JNI modules can be harmful is enough and has been evident since JNI exists, so what has changed all of a sudden?
> The linked JEP explains that in the “Why Now” section. In short: because the JDK is now changing faster than it ever did before, because more and more of it is being written in Java, and because the security threat landscape has changed.
Yes, I have read that JEP and it does not add a real reason IMHO that justifies a forceful,
unnecessary warning potentially scaring users of Java infrastructures away from using Java.
Maybe, can you just name one convincing reason (from the JEP) that justifies a forceful warning
about using JNI that would really make a difference to the current situation in which everyone
("application developers") realize what JNI is about and what it allows for? And that justifies to
have end-users, application users be confronted with such warnings?
>> • Deployment of Java: there seems to be the wrong assumption among some developers that Java is not being used as a JRE (non-JRE bubble?) which is simply wrong. What should applications do in a scenario in which the JVM gets dynamically loaded via JNI to then interact with the JRE? Is that considered to be dangerous such that it needs to be made seen by the "user" each time this demand loading of the JVM happens as otherwise the "user" does not realize that theoretically a potential danger exists (and if so for whom)?
> I’m not sure what you mean by JRE (the JRE is something that no longer exists),
This is simply not true and it is a little bit frightening that you seem to believe what you write
(and probably your peers as well)!
> but the JEP addresses the use of the invocation API. Obviously, whatever launcher is used is controlled by the application author, who can decide who can do what.
This is what is interesting for me: you (and quite a few people from the Java-application-only
"bubble") seem to only see this kind of Java usage, namely the creation of pure Java applications
(with customizable installers easying installation). Although, of course, these endeavors are
applauded and very important, it is by no means the only important usage of Java!
There are plenty of non-Java applications that just use the JRE! JAVA_HOME is your friend to switch
among the different JREs. JRE are alive and live well, thank you! :)
End user kind of people who after updating to the latest version of Java may be confronted with
warnings of using Java as it may be dangerous will be scared!
Seriously, it is a little bit frightening to learn that core Java developers think that the only
usage of Java is in creating pure Java applications, ignoring a simple fact: the JRE allows for
creating operating system independent applications, something no other infrastructure allows for in
a comparable manner! One can even create complex JavaFX GUI applications from the available JRE and
have them run unchanged on Windows, macOS and Linux, whether the operating system owners and
developers like it or not. [And for that reason alone it is damaging that the JavaFX modules are not
contained in the standard OpenJDK. Server/daemon Java apps would be able thanks to the module system
to exclude the four JavaFX modules when not needed, whereas JRE-kind of users would have immediate
access to JavaFX with a plain JDK installation.]
JRE gets employed heavily in non-Java applications whether one is aware of this fact or not.
>> • Who is really the "user" who gets addressed here? (How stupid is this particular "user" regarded to be?)
> The application author. The assumption is that they’ve somehow assembled a dependency graph and may not be aware whether any of the transitive dependencies have superpowers that may override the integrity guarantee that we’d like the JDK to make by default.
For an application author to learn about JNI being used in some of the modules it would be
sufficient to get a warning/information when running a tool that would tell her or him. Such an
application author would be able to learn from module-info entries (maybe via a tool) which modules
document their use of JNI.
In such a scenario it then would be probably acceptable that in the case that if modules at runtime
use JNI without having this usage documented in their module-info that then a warning gets issued to
make the application author aware of it (and only if the module is at least at the class file level
of the Java version that introduced this feature and should have been aware of this newly introduced
documentation obligation).
>> • Why is it not enough to simply record the fact that JNI gets employed explicitly in module-info? As has been mentioned a few times this would allow for appropriate analysis, if need be? (It also might suffice the intentions of the JEP in that the warnings get issued only if the fact that JNI gets employed in a module is not reported in its module-info.)
> Because, as the linked JEP explains (https://openjdk.org/jeps/8305968) the goal is to gain the permission of the application’s author.
Well, if an application author is using modules that document JNI usage in their module-info, then
that permission is implicitly granted already. There is no need to issue warnings that scare the
users of such applications.
Also, an application author is not forced to grant any of the JDK modules explicitly the permission
to employ JNI, why not? (Of course because she or he trusts the authors of JDK. Such an application
author would trust the authors of the modules she or he employs in his application, so why come up
with a warning for those only?)
> A library cannot decide grant itself superpowers that could change any of the integrity guarantees made by the JDK. The application has to grant that permission to the library.
No, not the application the "application author" as you mentioned.
What integrity guarantees does the JDK give that a JNI author would want to intentionally and
forcefully break with the intent to harm the JDK? (And if a JNI author would do that intentionally
to harm the JDK then she or he can be traced down and made accountable for it.)
How can an "application author" assess what a JNI module does in detail, whether it is an
implementation that breaks "integrity guarantees made by the JDK" in a harmful way? How can an
"application author" grant anything about something she or he has no clues about?
The responsibility of JNI authors breaking what the JDK guarantees in any harmful manner lies
clearly in the hands of the JNI authors, not the "application author" who usually has no knowledge
of the black box she or he is using in form of JNI.
---
What may make sense is to make it explicitly known for a module whether the module employs JNI via
its module-info. This way tools can create reports about the usage of JNI and "application authors"
learn (maybe for the first time) about that fact.
If a module employs JNI without reporting it that may be regarded as not behaving like a good
citizen in the modular Java land and hence reporting the fact that module xyz employs JNI without
telling in its module-info at runtime. The resolution should be that the module author should
correct module-info to incorporate that information.
---rony
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jdk-dev/attachments/20230831/1c2283fc/attachment-0001.htm>
More information about the jdk-dev
mailing list