8338536: Permanently disable remote code downloading in JNDI

Reviewed-by: dfuchs
This commit is contained in:
Aleksei Efimov 2024-11-21 20:55:02 +00:00
parent 7709d435d0
commit cee74f9e67
11 changed files with 364 additions and 252 deletions

View file

@ -25,22 +25,10 @@
package com.sun.jndi.ldap;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
public final class VersionHelper {
private static final VersionHelper helper = new VersionHelper();
/**
* Determines whether classes may be loaded from an arbitrary URL code base.
*/
private static final boolean trustURLCodebase;
/**
* Determines whether objects may be deserialized or reconstructed from a content of
* 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' LDAP attributes.
@ -48,29 +36,13 @@ public final class VersionHelper {
private static final boolean trustSerialData;
static {
// System property to control whether classes may be loaded from an
// arbitrary URL code base
String trust = getPrivilegedProperty(
"com.sun.jndi.ldap.object.trustURLCodebase", "false");
trustURLCodebase = "true".equalsIgnoreCase(trust);
// System property to control whether classes are allowed to be loaded from
// 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' attributes.
String trustSerialDataSp = getPrivilegedProperty(
String trustSerialDataSp = System.getProperty(
"com.sun.jndi.ldap.object.trustSerialData", "false");
trustSerialData = "true".equalsIgnoreCase(trustSerialDataSp);
}
@SuppressWarnings("removal")
private static String getPrivilegedProperty(String propertyName, String defaultVal) {
PrivilegedAction<String> action = () -> System.getProperty(propertyName, defaultVal);
if (System.getSecurityManager() == null) {
return action.run();
} else {
return AccessController.doPrivileged(action);
}
}
private VersionHelper() {
}
@ -89,41 +61,12 @@ public final class VersionHelper {
return trustSerialData;
}
ClassLoader getURLClassLoader(String[] url) throws MalformedURLException {
ClassLoader parent = getContextClassLoader();
/*
* Classes may only be loaded from an arbitrary URL code base when
* the system property com.sun.jndi.ldap.object.trustURLCodebase
* has been set to "true".
*/
if (url != null && trustURLCodebase) {
return URLClassLoader.newInstance(getUrlArray(url), parent);
} else {
return parent;
}
}
Class<?> loadClass(String className) throws ClassNotFoundException {
return Class.forName(className, true, getContextClassLoader());
return Class.forName(className, true,
Thread.currentThread().getContextClassLoader());
}
Thread createThread(Runnable r) {
return new Thread(r);
}
@SuppressWarnings("removal")
private ClassLoader getContextClassLoader() {
PrivilegedAction<ClassLoader> act =
Thread.currentThread()::getContextClassLoader;
return AccessController.doPrivileged(act);
}
@SuppressWarnings("deprecation")
private static URL[] getUrlArray(String[] url) throws MalformedURLException {
URL[] urlArray = new URL[url.length];
for (int i = 0; i < urlArray.length; i++) {
urlArray[i] = new URL(url[i]);
}
return urlArray;
}
}