From 1318bdf2dd20a10862ee8b75d9d7d724da947b7d Mon Sep 17 00:00:00 2001 From: Rundeck CI Date: Tue, 6 Jan 2026 10:37:32 -0800 Subject: [PATCH 1/5] Security fix: Disable external extension loading by default (RUN-3540) - Changed RD_EXT_DISABLED default from false to true in Main.java - Extension directory loading now disabled by default to prevent arbitrary code execution - Users must explicitly set RD_EXT_DISABLED=false to enable external extensions - Updated CHANGELOG.md for version 2.0.10 - Added MainSpec test for Main class constants - Updated .gitignore to exclude bin/ directories Addresses security vulnerability where malicious JAR files could be loaded via RD_EXT_DIR environment variable, executing code through static initializers without user interaction. --- .gitignore | 2 ++ CHANGELOG.md | 6 +++++ .../java/org/rundeck/client/tool/Main.java | 2 +- .../org/rundeck/client/tool/MainSpec.groovy | 22 +++++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 rd-cli-tool/src/test/groovy/org/rundeck/client/tool/MainSpec.groovy diff --git a/.gitignore b/.gitignore index ede9d588..72453241 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ /.idea /build */build +/bin +*/bin */out *.ipr *.iml diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e9a576e..91a7a015 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.0.10 + +* **Security Fix**: External extension directory loading is now disabled by default to prevent arbitrary code execution vulnerability. To enable extension loading from external directories, set environment variable `RD_EXT_DISABLED=false`. (Addresses RUN-3540) + +[Changes](https://github.com/rundeck/rundeck-cli/compare/v2.0.9...v2.0.10) + ## 2.0.9 * fix: NPE if system info does not return all data diff --git a/rd-cli-tool/src/main/java/org/rundeck/client/tool/Main.java b/rd-cli-tool/src/main/java/org/rundeck/client/tool/Main.java index db1f6cf9..f008f4a8 100644 --- a/rd-cli-tool/src/main/java/org/rundeck/client/tool/Main.java +++ b/rd-cli-tool/src/main/java/org/rundeck/client/tool/Main.java @@ -196,7 +196,7 @@ private static ConfigSource buildConfig() { } private static void loadExtensionJars(ConfigSource config) { - if (config.getBool(RD_EXT_DISABLED, false)) { + if (config.getBool(RD_EXT_DISABLED, true)) { return; } String rd_ext_dir = config.get(RD_EXT_DIR); diff --git a/rd-cli-tool/src/test/groovy/org/rundeck/client/tool/MainSpec.groovy b/rd-cli-tool/src/test/groovy/org/rundeck/client/tool/MainSpec.groovy new file mode 100644 index 00000000..21c76d66 --- /dev/null +++ b/rd-cli-tool/src/test/groovy/org/rundeck/client/tool/MainSpec.groovy @@ -0,0 +1,22 @@ +package org.rundeck.client.tool + +import spock.lang.Specification + +/** + * Test for Main class + * Note: Extension loading security behavior is tested through integration tests + * and verified by the default value of RD_EXT_DISABLED in Main.java + */ +class MainSpec extends Specification { + + def "RD_EXT_DISABLED constant is defined"() { + expect: "RD_EXT_DISABLED constant exists" + Main.RD_EXT_DISABLED == "RD_EXT_DISABLED" + } + + def "RD_EXT_DIR constant is defined"() { + expect: "RD_EXT_DIR constant exists" + Main.RD_EXT_DIR == "RD_EXT_DIR" + } +} + From 7bdcb112f601b406a7a1da0d3bd9e0587045e703 Mon Sep 17 00:00:00 2001 From: Forrest Evans Date: Mon, 12 Jan 2026 14:32:33 -0800 Subject: [PATCH 2/5] Update CHANGELOG.md Co-authored-by: Greg Schueler --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91a7a015..4af01f80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,7 @@ -## 2.0.10 +## Unreleased * **Security Fix**: External extension directory loading is now disabled by default to prevent arbitrary code execution vulnerability. To enable extension loading from external directories, set environment variable `RD_EXT_DISABLED=false`. (Addresses RUN-3540) -[Changes](https://github.com/rundeck/rundeck-cli/compare/v2.0.9...v2.0.10) ## 2.0.9 From c4ed975f10caa3c476737b6a6c62d8b76fa09da4 Mon Sep 17 00:00:00 2001 From: Rundeck CI Date: Mon, 12 Jan 2026 14:36:21 -0800 Subject: [PATCH 3/5] Remove unnecessary MainSpec test file The test only verified that string constants equal themselves, which provides no value. The actual security behavior is covered by integration tests. --- .../org/rundeck/client/tool/MainSpec.groovy | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 rd-cli-tool/src/test/groovy/org/rundeck/client/tool/MainSpec.groovy diff --git a/rd-cli-tool/src/test/groovy/org/rundeck/client/tool/MainSpec.groovy b/rd-cli-tool/src/test/groovy/org/rundeck/client/tool/MainSpec.groovy deleted file mode 100644 index 21c76d66..00000000 --- a/rd-cli-tool/src/test/groovy/org/rundeck/client/tool/MainSpec.groovy +++ /dev/null @@ -1,22 +0,0 @@ -package org.rundeck.client.tool - -import spock.lang.Specification - -/** - * Test for Main class - * Note: Extension loading security behavior is tested through integration tests - * and verified by the default value of RD_EXT_DISABLED in Main.java - */ -class MainSpec extends Specification { - - def "RD_EXT_DISABLED constant is defined"() { - expect: "RD_EXT_DISABLED constant exists" - Main.RD_EXT_DISABLED == "RD_EXT_DISABLED" - } - - def "RD_EXT_DIR constant is defined"() { - expect: "RD_EXT_DIR constant exists" - Main.RD_EXT_DIR == "RD_EXT_DIR" - } -} - From a145c32e47a4d120ae93c56293b759db4e6ae6c9 Mon Sep 17 00:00:00 2001 From: Rundeck CI Date: Mon, 12 Jan 2026 14:44:33 -0800 Subject: [PATCH 4/5] Update packaging submodule to include new GPG key rotation Updates packaging submodule from 8077ed3 to 662b44a, which includes: - GPG key rotation (commit 5174e38) - New pubring.gpg with updated signing key - Archived old key as pubring20250228.gpg This should resolve the GPG signature verification failures in CI/CD. --- packaging | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging b/packaging index 8077ed34..662b44a7 160000 --- a/packaging +++ b/packaging @@ -1 +1 @@ -Subproject commit 8077ed34131de99217a3c1a1bd5545f6975c4f3a +Subproject commit 662b44a7975888008c8c5b5553e96ecb2293e1d3 From 43b5dd73f2bdc54eb7ee66a487a855a1cc4e6f02 Mon Sep 17 00:00:00 2001 From: Rundeck CI Date: Mon, 12 Jan 2026 14:55:35 -0800 Subject: [PATCH 5/5] Import archived GPG key for RPM upgrade test The upgrade test installs version 2.0.9 which was signed with the old GPG key before the recent key rotation. Import the archived key (pubring20250228.gpg) to allow verification of the 2.0.9 package signature during the upgrade test. --- dockers/install/upgrade-rpm/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/install/upgrade-rpm/Dockerfile b/dockers/install/upgrade-rpm/Dockerfile index 777bfae1..fd6e4be6 100644 --- a/dockers/install/upgrade-rpm/Dockerfile +++ b/dockers/install/upgrade-rpm/Dockerfile @@ -7,6 +7,7 @@ RUN which java RUN curl https://raw.githubusercontent.com/rundeck/packaging/main/scripts/rpm-setup.sh 2> /dev/null | bash -s rundeck RUN sed -i.bak s/gpgcheck=0/gpgcheck=1/ /etc/yum.repos.d/rundeck.repo RUN rpm --import https://raw.githubusercontent.com/rundeck/packaging/main/pubring.gpg +RUN rpm --import https://raw.githubusercontent.com/rundeck/packaging/main/pubring20250228.gpg RUN rpm --import https://docs.rundeck.com/keys/BUILD-GPG-KEY-20230105.key RUN yum -y install rundeck-cli