Browse Source

Update tbel to 1.2.10 and add sandbox security tests

Bump tbel dependency to 1.2.10 which blocks dangerous java.util
subpackages (logging, zip, jar, prefs, spi) in TBEL sandbox.
Add integration tests verifying sandbox blocks SocketHandler, ZipFile,
FileHandler, JarFile, Preferences, and LocaleServiceProvider.
pull/15585/head
Oleksandra Matviienko 2 months ago
parent
commit
739a33b721
  1. 84
      application/src/test/java/org/thingsboard/server/service/script/TbelInvokeServiceTest.java
  2. 2
      pom.xml

84
application/src/test/java/org/thingsboard/server/service/script/TbelInvokeServiceTest.java

@ -217,6 +217,90 @@ class TbelInvokeServiceTest extends AbstractTbelInvokeTest {
assertThat(compiledScriptsCache.getIfPresent(scriptIdToHash.get(scriptRemovedFromCache))).isNotNull();
}
@Test
void givenForbiddenSocketHandler_whenInvoking_thenThrowsRuntimeError() throws ExecutionException, InterruptedException {
UUID scriptId = evalScript("new java.util.logging.SocketHandler(\"127.0.0.1\", 9999)");
assertThatThrownBy(() -> invokeScript(scriptId, "{\"temperature\":25}"))
.isInstanceOf(ExecutionException.class)
.cause()
.isInstanceOf(TbScriptException.class)
.asInstanceOf(type(TbScriptException.class))
.satisfies(ex -> {
assertThat(ex.getErrorCode()).isEqualTo(TbScriptException.ErrorCode.RUNTIME);
assertThat(ex.getCause().getMessage()).contains("could not resolve class: java.util.logging.SocketHandler");
});
}
@Test
void givenForbiddenZipFile_whenInvoking_thenThrowsRuntimeError() throws ExecutionException, InterruptedException {
UUID scriptId = evalScript("new java.util.zip.ZipFile(\"/tmp/test.zip\")");
assertThatThrownBy(() -> invokeScript(scriptId, "{\"temperature\":25}"))
.isInstanceOf(ExecutionException.class)
.cause()
.isInstanceOf(TbScriptException.class)
.asInstanceOf(type(TbScriptException.class))
.satisfies(ex -> {
assertThat(ex.getErrorCode()).isEqualTo(TbScriptException.ErrorCode.RUNTIME);
assertThat(ex.getCause().getMessage()).contains("could not resolve class: java.util.zip.ZipFile");
});
}
@Test
void givenForbiddenFileHandler_whenInvoking_thenThrowsRuntimeError() throws ExecutionException, InterruptedException {
UUID scriptId = evalScript("new java.util.logging.FileHandler(\"/tmp/test.log\")");
assertThatThrownBy(() -> invokeScript(scriptId, "{\"temperature\":25}"))
.isInstanceOf(ExecutionException.class)
.cause()
.isInstanceOf(TbScriptException.class)
.asInstanceOf(type(TbScriptException.class))
.satisfies(ex -> {
assertThat(ex.getErrorCode()).isEqualTo(TbScriptException.ErrorCode.RUNTIME);
assertThat(ex.getCause().getMessage()).contains("could not resolve class: java.util.logging.FileHandler");
});
}
@Test
void givenForbiddenJarFile_whenInvoking_thenThrowsRuntimeError() throws ExecutionException, InterruptedException {
UUID scriptId = evalScript("new java.util.jar.JarFile(\"/tmp/test.jar\")");
assertThatThrownBy(() -> invokeScript(scriptId, "{\"temperature\":25}"))
.isInstanceOf(ExecutionException.class)
.cause()
.isInstanceOf(TbScriptException.class)
.asInstanceOf(type(TbScriptException.class))
.satisfies(ex -> {
assertThat(ex.getErrorCode()).isEqualTo(TbScriptException.ErrorCode.RUNTIME);
assertThat(ex.getCause().getMessage()).contains("could not resolve class: java.util.jar.JarFile");
});
}
@Test
void givenForbiddenPreferences_whenInvoking_thenThrowsRuntimeError() throws ExecutionException, InterruptedException {
UUID scriptId = evalScript("java.util.prefs.Preferences.userRoot()");
assertThatThrownBy(() -> invokeScript(scriptId, "{\"temperature\":25}"))
.isInstanceOf(ExecutionException.class)
.cause()
.isInstanceOf(TbScriptException.class)
.asInstanceOf(type(TbScriptException.class))
.satisfies(ex -> {
assertThat(ex.getErrorCode()).isEqualTo(TbScriptException.ErrorCode.RUNTIME);
assertThat(ex.getMessage()).contains("unresolvable property or identifier: java");
});
}
@Test
void givenForbiddenLocaleServiceProvider_whenInvoking_thenThrowsRuntimeError() throws ExecutionException, InterruptedException {
UUID scriptId = evalScript("new java.util.spi.LocaleServiceProvider()");
assertThatThrownBy(() -> invokeScript(scriptId, "{\"temperature\":25}"))
.isInstanceOf(ExecutionException.class)
.cause()
.isInstanceOf(TbScriptException.class)
.asInstanceOf(type(TbScriptException.class))
.satisfies(ex -> {
assertThat(ex.getErrorCode()).isEqualTo(TbScriptException.ErrorCode.RUNTIME);
assertThat(ex.getCause().getMessage()).contains("could not resolve class: java.util.spi.LocaleServiceProvider");
});
}
private void assertThatScriptIsBlocked(UUID scriptId) {
assertThatThrownBy(() -> {
invokeScriptResultString(scriptId, "{}");

2
pom.xml

@ -92,7 +92,7 @@
<zookeeper.version>3.9.5</zookeeper.version> <!-- to fix CVE-2026-24308 and CVE-2026-24281. TODO: remove override when fixed in curator-client -->
<protobuf.version>3.25.5</protobuf.version> <!-- A Major v4 does not support by the pubsub yet-->
<grpc.version>1.76.0</grpc.version>
<tbel.version>1.2.9</tbel.version>
<tbel.version>1.2.10</tbel.version>
<lombok.version>1.18.46</lombok.version> <!-- must be in sync with spring-boot-dependencies; needed for maven-compiler-plugin annotationProcessorPaths -->
<paho.client.version>1.2.5</paho.client.version>
<paho.mqttv5.client.version>1.2.5</paho.mqttv5.client.version>

Loading…
Cancel
Save