Permanently switch from SecurityManager to Entitlements (#124865) (#125117)

The JDK team has completely disabled the Java SecurityManager from Java 24. Elasticsearch has always used the Java SecurityManager as an additional protection mechanism; in order to retain this second line of defense, the Elasticsearch Core/Infra team has been working on the Entitlements project.

Similar to SecurityManager, Entitlements only allow calling specific methods in the JDK when the caller has a matching policy attached. In other words, if some code (in the main Elasticsearch codebase, in a plugin/module, or in a script) attempts to perform a "privileged" operation and it is not entitled to do so, a NotEntitledException will be thrown.

This PR includes the minimal set of changes to always use Entitlements, regardless of system properties or Java version.

Relates to ES-10921
This commit is contained in:
Lorenzo Dematté 2025-03-18 17:38:45 +01:00 committed by GitHub
parent 11961730da
commit a4d7297944
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 18 additions and 22 deletions

View file

@ -42,7 +42,7 @@ public abstract class RunTask extends DefaultTestClustersTask {
private Boolean debug = false;
private Boolean cliDebug = false;
private Boolean entitlementsEnabled = false;
private Boolean apmServerEnabled = false;
private Boolean preserveData = false;
@ -74,9 +74,7 @@ public abstract class RunTask extends DefaultTestClustersTask {
option = "entitlements",
description = "Use the Entitlements agent system in place of SecurityManager to enforce sandbox policies."
)
public void setEntitlementsEnabled(boolean enabled) {
this.entitlementsEnabled = enabled;
}
public void setEntitlementsEnabled(boolean enabled) {}
@Input
public Boolean getDebug() {
@ -90,7 +88,7 @@ public abstract class RunTask extends DefaultTestClustersTask {
@Input
public Boolean getEntitlementsEnabled() {
return entitlementsEnabled;
return true;
}
@Input
@ -240,9 +238,7 @@ public abstract class RunTask extends DefaultTestClustersTask {
if (cliDebug) {
enableCliDebug();
}
if (entitlementsEnabled) {
enableEntitlements();
}
enableEntitlements();
}
@TaskAction

View file

@ -11,7 +11,6 @@ package org.elasticsearch.server.cli;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.core.Booleans;
import org.elasticsearch.jdk.RuntimeVersionFeature;
import java.io.IOException;
@ -28,9 +27,8 @@ final class SystemJvmOptions {
String distroType = sysprops.get("es.distribution.type");
String javaType = sysprops.get("es.java.type");
boolean isHotspot = sysprops.getOrDefault("sun.management.compiler", "").contains("HotSpot");
boolean entitlementsExplicitlyEnabled = Booleans.parseBoolean(sysprops.getOrDefault("es.entitlements.enabled", "true"));
// java 24+ only supports entitlements, but it may be enabled on earlier versions explicitly
boolean useEntitlements = RuntimeVersionFeature.isSecurityManagerAvailable() == false || entitlementsExplicitlyEnabled;
boolean useEntitlements = true;
return Stream.of(
Stream.of(
/*

View file

@ -0,0 +1,8 @@
pr: 125117
summary: "Permanently switch from Java SecurityManager to Entitlements.
The Java SecurityManager has been deprecated since Java 17, and it is now completely disabled in Java 24. In order
to retain an similar level of protection, Elasticsearch implemented its own protection mechanism, Entitlements.
Starting with this version, Entitlements will permanently replace the Java SecurityManager."
area: Infra/Core
type: upgrade
issues: []

View file

@ -18,11 +18,9 @@ import org.apache.tika.parser.Parser;
import org.apache.tika.parser.ParserDecorator;
import org.elasticsearch.SpecialPermission;
import org.elasticsearch.bootstrap.FilePermissionUtils;
import org.elasticsearch.core.Booleans;
import org.elasticsearch.core.PathUtils;
import org.elasticsearch.core.SuppressForbidden;
import org.elasticsearch.jdk.JarHell;
import org.elasticsearch.jdk.RuntimeVersionFeature;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@ -129,9 +127,7 @@ final class TikaImpl {
: null;
private static boolean isUsingSecurityManager() {
boolean entitlementsEnabled = Booleans.parseBoolean(System.getProperty("es.entitlements.enabled"), false)
|| RuntimeVersionFeature.isSecurityManagerAvailable() == false;
return entitlementsEnabled == false;
return false;
}
// compute some minimal permissions for parsers. they only get r/w access to the java temp directory,

View file

@ -29,7 +29,6 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.BoundTransportAddress;
import org.elasticsearch.common.util.concurrent.RunOnce;
import org.elasticsearch.core.AbstractRefCounted;
import org.elasticsearch.core.Booleans;
import org.elasticsearch.core.CheckedConsumer;
import org.elasticsearch.core.IOUtils;
import org.elasticsearch.core.SuppressForbidden;
@ -129,9 +128,8 @@ class Elasticsearch {
final PrintStream out = getStdout();
final PrintStream err = getStderr();
final ServerArgs args;
final boolean entitlementsEnabled = Booleans.parseBoolean(System.getProperty("es.entitlements.enabled", "true"));
// java 24+ only supports entitlements, but it may be enabled on earlier versions explicitly
final boolean useEntitlements = RuntimeVersionFeature.isSecurityManagerAvailable() == false || entitlementsEnabled;
final boolean useEntitlements = true;
try {
initSecurityProperties();

View file

@ -36,7 +36,7 @@ import static org.elasticsearch.example.role.CustomInMemoryRolesProvider.ROLE_B;
public class ExampleSecurityExtension implements SecurityExtension {
static {
final boolean useEntitlements = Boolean.parseBoolean(System.getProperty("es.entitlements.enabled"));
final boolean useEntitlements = true;
if (useEntitlements == false && RuntimeVersionFeature.isSecurityManagerAvailable()) {
// check that the extension's policy works.
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {