I'm trying to understand the security model used when the JVM is asked to load classes.
From the JVM specification on Sandboxing, I'm given to believe that a standard JVM implementation should maintain at least one other ClassLoader
, independent of the primordial ClassLoader
. This is used to load the application class files (from a provided classpath for example).
If the class is requested from the ClassLoader
that is not in it's namespace, java/lang/String
for example, then it forwards the request to the primordial ClassLoader
, which attempts to load the class from the Java API, if its not there then it throws a NoClassDefFoundError
.
Am I right in thinking that the primordial ClassLoader
only loads classes from the Java API namespace, and all other classes are loaded via a separate ClassLoader
implementation?
And that this makes the loading of classes more secure because it means that a malicious class cannot masquerade as a member of the Java API (lets say java/lang/Virus
) because this is a protected namespace, and cannot be used in the current ClassLoader
?
But is there anything to prevent the Classes of the Java API being replaced by malicious classes, or would that be detected during class
verification?
The Java security model is based on controlling the operations that a class can perform when it is loaded into a running environment. For this reason, this model is called code-centric or code-based.
The Java ClassLoader is a part of the Java Runtime Environment that dynamically loads Java classes into the Java Virtual Machine. The Java run time system does not need to know about files and file systems because of classloaders. Java classes aren't loaded into memory all at once, but when required by an application.
A Java Class is stored in the form of byte code in a . class file after it is compiled. The ClassLoader loads the class of the Java program into memory when it is required. The ClassLoader is hierarchical and so if there is a request to load a class, it is delegated to the parent class loader.
Class loaders are responsible for loading Java classes dynamically to the JVM (Java Virtual Machine) during runtime. They're also part of the JRE (Java Runtime Environment). Therefore, the JVM doesn't need to know about the underlying files or file systems in order to run Java programs thanks to class loaders.
For historical reasons the names used for class loaders are a little peculiar. The boot class loader loads the systems classes. The system class loader, by default, loads classes from the class path not the system classes. The system classes are in jre/lib (mostly in rt.jar), endorsed directories and anywhere added through -Xbootclasspath
.
On the Sun/Oracle JRE, rt.jar contains classes with packages starting with java., javax., sun., com.sun., org.omg, org.w3c and org.xml.
Untrusted code (including configuration) should not be able to add to the system classes. Some packages name prefixed may be restricted through a security property. The java. prefix is specially protected against for non-technical reasons.
Generally a class loader will delegate to its parent before defining a new class, preventing any classes from an ancestor loader from being replaced. Java EE recommends (even though Java SE bans) having some class loaders prefer their own classes, typically to use a more up to date API or a different implementation. This allows shadowing of classes, but only as seen through that loader (and its children). All other classes continue to link to the original.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With