This is an automated email from the ASF dual-hosted git repository.
jbonofre pushed a commit to branch karaf-4.4.x
in repository https://gitbox.apache.org/repos/asf/karaf.git
The following commit(s) were added to refs/heads/karaf-4.4.x by this push:
new 044278e704 fix(config): restrict config:install to the admin role
(#2862)
044278e704 is described below
commit 044278e704428a955edfe3262d9691d0aa2f27ea
Author: JB Onofré <[email protected]>
AuthorDate: Fri Sep 11 14:48:26 2026 +0200
fix(config): restrict config:install to the admin role (#2862)
config:install writes a file fetched from an arbitrary URL into
${karaf.etc}, which also holds users.properties, keys.properties and the
*.acl.* files. The command had no entry in the
org.apache.karaf.command.acl.config
ACL, and the command guard treats an unmatched command as allowed, so any
authenticated shell user could run it.
Add "install = admin" to the config command ACL, consistent with
config:delete and with bundle:install / feature:install / kar:install.
---
.../features/standard/src/main/feature/feature.xml | 6 +++++
.../etc/org.apache.karaf.command.acl.config.cfg | 6 +++++
.../src/test/filtered-resources/etc/feature.xml | 6 +++++
.../itests/ssh/ConfigSshCommandSecurityTest.java | 30 ++++++++++++++++++++++
manual/src/main/asciidoc/user-guide/security.adoc | 3 ++-
5 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/assemblies/features/standard/src/main/feature/feature.xml
b/assemblies/features/standard/src/main/feature/feature.xml
index 1165ab838e..c52c66c891 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -616,6 +616,12 @@ edit = manager
edit[/.*jmx[.]acl.*/] = admin
edit[/.*org[.]apache[.]karaf[.]command[.]acl[.].+/] = admin
edit[/.*org[.]apache[.]karaf[.]service[.]acl[.].+/] = admin
+#
+# 'install' writes an arbitrary file (fetched from a URL) into ${karaf.etc},
which
+# includes the users, keys and *.acl.* configuration files. It is restricted to
+# 'admin', consistent with bundle:install, feature:install and kar:install.
+#
+install = admin
property-append = manager
property-append[/.*jmx[.]acl.*/] = admin
property-append[/.*org[.]apache[.]karaf[.]command[.]acl[.].+/] = admin
diff --git
a/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.command.acl.config.cfg
b/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.command.acl.config.cfg
index 1cbc8b5cd8..89336fd4f1 100644
---
a/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.command.acl.config.cfg
+++
b/instance/src/main/resources/org/apache/karaf/instance/resources/etc/org.apache.karaf.command.acl.config.cfg
@@ -29,6 +29,12 @@ edit = manager
edit[/.*jmx[.]acl.*/] = admin
edit[/.*org[.]apache[.]karaf[.]command[.]acl[.].+/] = admin
edit[/.*org[.]apache[.]karaf[.]service[.]acl[.].+/] = admin
+#
+# 'install' writes an arbitrary file (fetched from a URL) into ${karaf.etc},
which
+# includes the users, keys and *.acl.* configuration files. It is restricted to
+# 'admin', consistent with bundle:install, feature:install and kar:install.
+#
+install = admin
property-append = manager
property-append[/.*jmx[.]acl.*/] = admin
property-append[/.*org[.]apache[.]karaf[.]command[.]acl[.].+/] = admin
diff --git a/itests/test/src/test/filtered-resources/etc/feature.xml
b/itests/test/src/test/filtered-resources/etc/feature.xml
index 023bd2981d..b34dfff46a 100644
--- a/itests/test/src/test/filtered-resources/etc/feature.xml
+++ b/itests/test/src/test/filtered-resources/etc/feature.xml
@@ -411,6 +411,12 @@
edit[/.*jmx[.]acl.*/] = admin
edit[/.*org[.]apache[.]karaf[.]command[.]acl[.].+/] = admin
edit[/.*org[.]apache[.]karaf[.]service[.]acl[.].+/] = admin
+ #
+ # 'install' writes an arbitrary file (fetched from a URL) into
${karaf.etc}, which
+ # includes the users, keys and *.acl.* configuration files. It
is restricted to
+ # 'admin', consistent with bundle:install, feature:install and
kar:install.
+ #
+ install = admin
property-append = manager
property-append[/.*jmx[.]acl.*/] = admin
property-append[/.*org[.]apache[.]karaf[.]command[.]acl[.].+/]
= admin
diff --git
a/itests/test/src/test/java/org/apache/karaf/itests/ssh/ConfigSshCommandSecurityTest.java
b/itests/test/src/test/java/org/apache/karaf/itests/ssh/ConfigSshCommandSecurityTest.java
index 9388828fef..77f3080e05 100644
---
a/itests/test/src/test/java/org/apache/karaf/itests/ssh/ConfigSshCommandSecurityTest.java
+++
b/itests/test/src/test/java/org/apache/karaf/itests/ssh/ConfigSshCommandSecurityTest.java
@@ -13,6 +13,9 @@
*/
package org.apache.karaf.itests.ssh;
+import java.io.File;
+
+import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.junit.PaxExam;
@@ -52,6 +55,33 @@ public class ConfigSshCommandSecurityTest extends
SshCommandTestBase {
testConfigEdits("karaf", Result.OK,
"org.apache.karaf.service.acl.test_" + counter++, true);
}
+ @Test
+ public void testConfigInstallCommandSecurityViaSsh() throws Exception {
+ // Skip on Windows where PTY output can be garbled,
+ // when upgrading to Junit5, this can be replaced with
@DisabledOnOs(OS.WINDOWS)
+ // TODO: remove this once we have a better solution for PTY output on
Windows
+ Assume.assumeFalse(System.getProperty("os.name",
"").toLowerCase().contains("win"));
+
+ String manageruser = "man" + System.nanoTime() + "_" + counter++;
+ String vieweruser = "view" + System.nanoTime() + "_" + counter++;
+
+ addUsers(manageruser, vieweruser);
+
+ String sourceUrl = new File(System.getProperty("karaf.etc"),
"system.properties").toURI().toURL().toString();
+
+ // config:install writes an arbitrary file under ${karaf.etc}, so it
is restricted to admin.
+ // A viewer and a manager must not even see the command.
+ assertCommand(vieweruser, "config:install " + sourceUrl + " itest-" +
counter++ + ".cfg", Result.NOT_FOUND);
+ assertCommand(manageruser, "config:install " + sourceUrl + " itest-" +
counter++ + ".cfg", Result.NOT_FOUND);
+
+ // The admin user can run it: the first install succeeds, a second one
without --override
+ // reports that the file already exists, which proves the file was
written.
+ String target = "itest-installed-" + counter++ + ".cfg";
+ assertCommand("karaf", "config:install " + sourceUrl + " " + target,
Result.OK);
+ assertContains("already exists",
+ assertCommand("karaf", "config:install " + sourceUrl + " " +
target, Result.OK));
+ }
+
private void testConfigEdits(String user, Result expectedEditResult,
String pid, boolean isAdmin) throws Exception {
assertCommand(user, "config:edit " + pid + "\n" +
"config:property-set x y\n" +
diff --git a/manual/src/main/asciidoc/user-guide/security.adoc
b/manual/src/main/asciidoc/user-guide/security.adoc
index a3365778f2..a542b88994 100644
--- a/manual/src/main/asciidoc/user-guide/security.adoc
+++ b/manual/src/main/asciidoc/user-guide/security.adoc
@@ -489,7 +489,8 @@ By default, Apache Karaf defines the following commands
ACLs:
* `etc/org.apache.karaf.command.acl.config.cfg` configuration file defines the
ACL for `config:*` commands.
This ACL limits the execution of `config:*` commands with `jmx.acl.*`,
`org.apache.karaf.command.acl.*`, and
`org.apache.karaf.service.acl.*` configuration PID to the users with `admin`
role. For the other configuration PID,
- the users with the `manager` role can execute `config:*` commands.
+ the users with the `manager` role can execute `config:*` commands. As
`config:install` writes an arbitrary file into
+ the `etc` folder, it is restricted to the users with the `admin` role.
* `etc/org.apache.karaf.command.acl.feature.cfg` configuration file defines
the ACL for `feature:*` commands.
Only the users with `admin` role can execute `feature:install`,
`feature:uninstall`,`feature:start`, `feature:stop` and `feature:update`
commands. The other `feature:*`
commands can be executed by any user.