JVM - Java Virtual Machine Corruption - java

How can I check and detect a JVM corrupted?
How can I check that Security Manager, Byte Code Verifier and Class Loader are working correctly?

How can I check and detect a JVM corrupted? How can I check that Security Manager, Byte Code Verifier and Class Loader are working correctly?
You would do this the same way you would do for any other process. Typically, you would use a HIDS (Host Intrusion Detection System) that would detect if any changes are made to files. In your case, you would need a HIDS system that is capable of detecting changes to the filesystem, especially for the artifacts that constitute the runtime - the java executable and related shared libraries, and the runtime classes of the JRE. As long as the HIDS has been configured to detect changes to these files, you would not need any extraneous mechanisms for protecting them.
I've mostly encountered the use of Samhain and Tripwire for this purpose. There could be other HIDS systems that are also capable of this task.
You should not expect to find any mechanisms within the JVM itself that will detect if the JVM installation has been compromised, after such a mechanism itself could be compromised first, leading to a false belief that the JVM is trustworthy.

Related

WASI and JVM - OS Abstraction

My question is if the JVM actually provides a virtual operating system too, similar to how WASI does.
As for my understand WASM and JVM are both virtual machines, providing an environment to execute some bytecode. Their aim is to abstract the machine layer, thus CPU (architecture) and its' ISA.
WASM itself has no access to other system resources (fs, networking, ...) because of it's sandbox design. That's where WASI, as an extension to WASM, provides an abstract operating system layer, so that system resources can be accessed.
For Java applications, I can use native (Java) APIs, such as java.io/java.nio or java.net, directly on the JVM.
I understand that both approaches handle security differently. E.g. I do not need to provide access to a file myself to a Java application, but as with WASI I do need to. My question is rather if they conceptually provide similar levels of abstractions in case of the OS.
source to WASI: https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/
EDIT: We continued discussing in the WASI repository. https://github.com/WebAssembly/WASI/issues/439

How can dynamic JVM command line flags be passed to a self-contained JavaFX application?

EDIT: Oracle accept my bug report requesting an enhancement as JDK-8138944 : Support command line arguments to the JVM passed to self-contained app launchers.
The problem
My team is working on an open source Java SE project, ImageJ, that currently has a custom native launcher written in cross-platform C. We would like to move away from this launcher, switching to a more modern, industry standard and maintainable deployment mechanism. JavaFX self-contained applications are the most promising solution we have found so far.
One great feature of ImageJ's current native launcher is its ability to customize how the JVM is launched. For example, you can write:
ImageJ --debugger=8000 myFile.png
And the launcher will invoke the JVM with flag:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=localhost:8000
while keeping the myFile.png as an argument to the Java main class.
But from the docs, we cannot see a way to accomplish something similar with the JavaFX packaging tool.
Considerations
I know that the UserJvmOptionsService provides a means to configure how the JVM is started (via Java Preferences API internally, which the JavaFX launcher reads before JVM startup). This is nice for providing the user with a friendly dialog box where they can tweak maximum heap size and other common parameters. Certainly we could add a remote debugging toggle and port settings to such a dialog box, and/or support JVM configuration via the CLI—but it would then require a restart of the application.
Ideally we would not need to support this scenario at all, and instead would handle all command line arguments after the JVM starts up, in Java. For example, in most cases, system properties of the form -Dfoo=bar can be supported by simply parsing the arg and setting the system property at runtime, as long as it is done early enough in the application's startup cycle. But there are clearly many cases where doing it after JVM startup is too late:
The debugging example above (you can't enable remote debugging after startup).
Heap size tuning
Garbage collection tuning
Verbose class loading (-verbose)
Interpreted mode (-Xint)
Lots of other examples
Our users expect to be able to pass these settings on the CLI, and have the Java runtime operate accordingly—and in the case of ImageJ, it is particularly important for backward compatibility.
Possible solutions
We could retain the native C launcher, replacing the native executable that the Java packaging tool installs. But this strikes me as highly fragile, and largely defeats the purpose of switching to JavaFX deployment, since we would still need to maintain, build and test the custom native launcher across several different platforms.
Alternately, we could have the application main class be a very thin CLI option parser, which then spawns a second instance of the JVM. This would keep the bootstrapping logic in pure Java, which would be far more maintainable than the current native C code, while fully leveraging the JavaFX deployment scheme's cross-platform bundling capabilities. But that seems like a big hack with potentially challenging side effects.
Finally, the question
Has anyone achieved support for JVM CLI arguments with JavaFX self-contained application deployment? If so, how did you accomplish it? If not, any alternative suggestions?
You can modify the launch arguments to the JVM by modifying the jvm user overrides config file that the API writes to:
• Mac ~/Library/Application Support/[app.preferences.id]/packager/jvmuserargs.cfg
• Windows C:\Users[username]\AppData\Roaming[app.preferences.id]\packager\jvmuserargs.cfg
• Linux ~/.local/[app.preferences.id]/packager/jvmuserargs.cfg
NOTE: This is an internal implementation detail and subject to change.
Rather than having any kind of two-phase launch system, where you see what options you have and then launch a replacement JVM, I would suggest you create your own native launcher by copying and editing the platform java.c launcher. You can see what they are doing in the open JDK project.
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/914cd9b482c8/src/share/bin/java.c
There are quite a few places where they are looking for various options and converting them into init arguments for the JVM itself. Take a look at the functions ParseArguments, AddApplicationOptions, TranslateApplicationArgs, CheckJvmType, AddOption etc.
I am no C programmer but I have maintained my own launcher on quite a few occasions: such as a launcher that loaded a specific class path from a one-entry-per-line text file that could be checked into source control and one that used a different entry point to main(). It doesn't change that much and you can isolate your changes quite easily, so that they are easy to reapply on later versions of java.c. For your purposes, you would not really need to change every time someone makes a change to java.c, you only really need to change it when JavaVMInitArgs or some other critical aspect of the invocation interface changes.
I am sure that if you proposed and contributed a more elegant option-handling solution, maybe one that behaved differently when argv[0] is not 'java', then maybe the open jdk team would adopt your approach and maintain it for you, or for all us. I am sure there are lots of developers out there needing features like these.

Executing Java byte-code in a very restricted part of a running JVM

Is there a way to run some java byte-code into a specially restricted part of a running JVM ? I'm thinking about access to very little ram (a few tens of kilobytes perhaps) and no access to the external world whatsoever (apart from that ram).
The goal would be to execute some user provided byte-code into this safe environment in a way that the host cannot ever crash or leak information from the execution of rogue byte-code.
You can run untrusted bytecodes within a security sandbox, and setup the sandbox so that there is no possibility of communicating with the outside world. This is what a browser-resident JVM does when you run an untrusted applet ... except that you need the sandbox restrictions to be tighter. (An applet sandbox doesn't block ALL network connections.)
Reference: How do I create a Java sandbox?
However, it is NOT POSSIBLE to entirely control what the rogue code does. For example, if it decides to go into an infinite loop or allocate a huge data structure, the trusted part of your JVM has no bomb-proof way of stopping it. And if there is a security flaw in the JVM, class libraries or your sandbox, then there's a chance that the rogue code could exploit it.
Note that none of this involves restricting the code to a particular area of RAM. You can't do that in Java.
You could use JavaPathfinder (JPF) for this type of exercise. JPF is a model checking tool that takes a source-code/byte-code and executes it in its own virtual machine, you can define various properties (deadlock-free, infinite loops, etc.) to check for.
JPF operates as a self-standing tool so it would be hard to integrate it in your application but perhaps you could call it externally and then just query for results.

What are common Java vulnerabilities?

What are common Java vulnerabilities that can be exploited to gain some sort of access to a system? I have been thinking about it recently, and havent been able to come up with much of anything - integer overflow - maybe? race condition - what does it give you?
I am not looking for things like "sql injection in a web app". I am looking for a relationship similar to buffer overflow - c/c++.
Any security experts out there that can help out? Thanks.
Malicious Code injection.
Because Java (or any language using an interpreter at runtime), performs linkage at runtime, it is possible to replace the expected JARs (the equivalent of DLLs and SOs) with malicious ones at runtime.
This is a vulnerability, which is combated since the first release of Java, using various mechanisms.
There are protections in places in the classloaders to ensure that java.* classes cannot be loaded from outside rt.jar (the runtime jar).
Additionally, security policies can be put in place to ensure that classes loaded from different sources are restricted to performing only a certain set of actions - the most obvious example is that of applets. Applets are constrained by the Java security policy model from reading or writing the file system etc; signed applets can request for certain permissions.
JARs can also be signed, and these signatures can be verified at runtime when they're loaded.
Packages can also be sealed to ensure that they come from the same codesource. This prevents an attacker from placing classes into your package, but capable of performing 'malicious' operations.
If you want to know why all of this is important, imagine a JDBC driver injected into the classpath that is capable of transmitting all SQL statements and their results to a remote third party. Well, I assume you get the picture now.
After reading most of the responses I think your question has been answered in an indirect way. I just wanted to point this out directly. Java doesn't suffer from the same problems you see in C/C++ because it protects the developer from these types of memory attacks (buffer overflow, heap overflow, etc). Those things can't happen. Because there is this fundamental protection in the language security vulnerabilities have moved up the stack.
They're now occurring at a higher level. SQL injection, XSS, DOS, etc. You could figure out a way to get Java to remotely load malicious code, but to do that would mean you'd need to exploit some other vulnerability at the services layer to remotely push code into a directory then trigger Java to load through a classloader. Remote attacks are theoretically possible, but with Java it's more complicated to exploit. And often if you can exploit some other vulnerability then why not just go after and cut java out of the loop. World writable directories where java code is loaded from could be used against you. But at this point is it really Java that's the problem or your sys admin or the vendor of some other service that is exploitable?
The only vulnerabilities that pose remote code potential I've seen in Java over the years have been from native code the VM loads. The libzip vulnerability, the gif file parsing, etc. And that's only been a handful of problems. Maybe one every 2-3 years. And again the vuln is native code loaded by the JVM not in Java code.
As a language Java is very secure. Even these issues I discussed that can be theoretically attacked have hooks in the platform to prevent them. Signing code thwarts most of this. However, very few Java programs run with a Security Manager installed. Mainly because of performance, usability, but mainly because these vulns are very limited in scope at best. Remote code loading in Java hasn't risen to epidemic levels that buffer overflows did in the late 90s/2000s for C/C++.
Java isn't bullet proof as a platform, but it's harder to exploit than the other fruit on the tree. And hackers are opportunistic and go for that low hanging fruit.
I'm not a security expert, but there are some modules in our company that we can't code in java because it is so easy to de-compile java bytecode. We looked at obfuscation but if you want real obfuscation it comes only with a lot of problems (performance hit/loss of debug information).
One could steal our logics, replace the module with a modified version that will return incorrect results etc...
So compared to C/C++, I guess this is one "vulnerability" that stands out.
We also have a software license mechanism built-in in our java modules, but this can also be easily hacked by de-compiling and modifying the code.
Including third party class files and calling upon them basically means you are running unsecure code. That code can do anything it wants if you don't have security turned on.

Does Java have a built-in Antivirus? Is it true?

Does Java have a built-in Antivirus?
One of my friends told me there is in the JVM itself - it's called the "sandbox". Is it true?
Java does have a security-related concept called "sandbox", but it works very differently from typical anti-virus products. The latter usually try to catch viruses via signatures or code analysis before they are executed.
The Java sandbox on the other hand allows you to run Java code while witholding from it access to system resources that could be used to to bad things, e.g. no access to any files.
However, only Java applets and Java Web Start applications run in a sandbox per default. Regular java applications have full access to your system.
Doubtful. Perhaps he was referring to the fact that the JVM (somewhat) sandboxes execution of a Java program, to help prevent it from damaging the host OS.
No they do not have a built-in antivirus. Did he tell you this on April 1st?
To clear your doubt, sandbox is not an antivirus.
does the java have an in-built antivirus?
No.
Java has a security model built-in that allows it to execute untrusted code. This model is called "the sandbox model".
It is not a virus-scanner. Instead, it limits the possibilities of untrusted code so that applets on a webpage do not have access to files on your computer's hard drive.
You can read more about Java's Security Architecture.
java uses a class called SecurityManager to determine what a program can or cannot do, so in some sense it implements anti-exploit code, but not specifically anti-virus.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/SecurityManager.html
anti-virus in the usual sense of the word detects viruses in files and removes them. this is not built in to java.
No. What it does is running the program in an environment that is (somewhat) separated from the operating system, which should, in most cases, prevent malicious code from doing any damage. Sort of like running VMware - virii and other malware have no influence on the host OS.
I heard garbage collection also acts as a handy anti-bacterial, making your applications 99.99% free from germs.
Wash after every use.
The closest thing in the JRE to literal "anti-virus" is the blacklisting feature for signed jars. If a signed jar is found to cause a security issue, it can be blocked. This has been designed for accidental security flaws rather than blocking deliberately malicious code. Also it is possible to revoke a certificate using a CRL (Certificate Revocation List) or OCSP (Online Certificate Status Protocol) if enabled. Conventional anti-virus is left to specialist anti-virus products, rather than trying to produce a half-baked alternative.
(Today's anti-virus products do more than just check for known viruses.)

Categories