Severity: moderate
Affected versions:
- Apache Karaf before 4.4.12
Description:
Apache Karaf's shell/SSH command security is enforced by per-scope ACL
configuration files (etc/org.apache.karaf.command.acl.<scope>.cfg).
SecuredSessionFactoryImpl.checkSecurity() resolves the roles required for an
invocation and, when no ACL rule matches the command, fails open:
ACLConfigurationParser.Specificity.NO_MATCH sets passCheck = true. The safety
valve for this, karaf.secured.command.compulsory.roles, ships commented out in
etc/system.properties, so an unmatched command is allowed for any authenticated
user.
The shipped org.apache.karaf.command.acl.config ACL
(assemblies/features/standard/src/main/feature/feature.xml, mirrored into
instance/.../etc/org.apache.karaf.command.acl.config.cfg) has no install entry.
It restricts delete to admin, restricts edit/property-*/update on the
jmx.acl.*, org.apache.karaf.command.acl.* and org.apache.karaf.service.acl.*
PIDs to admin, and allows manager for everything else, but config:install was
simply unmatched, and therefore allowed for any authenticated user, including
one holding only the viewer role.
config:install <url> <finalname> fetches url and writes it into ${karaf.etc} as
finalname. It calls PathUtils.checkWithin() to block .. traversal outside
karaf.etc, but that folder holds every security-relevant file Karaf ships:
users.properties, keys.properties, host.key, and all org.apache.karaf.*.acl.*
files, including the very ACL file that (mis)governs this command. With
-o/--override, an existing file is overwritten with attacker-controlled bytes
fetched from an arbitrary URL.
Because felix.fileinstall.dir = ${karaf.etc} (etc/config.properties), Felix
FileInstall also watches and reloads any .cfg file dropped there, closing the
loop without requiring a restart.
By contrast, bundle:install, feature:install and kar:install are all admin-only
in their own ACLs, and config:delete is admin in this same ACL, config:install
was the outlier.
MitigationAdd install = admin in etc/org.apache.karaf.command.acl.config.cfg
(create the file is absent), and/or set
karaf.secured.command.compulsory.roles=admin in etc/system.properties (and
restart) to make unmatched commands fail closed by default.
Credit:
Rin Ray <[email protected]> (reporter)
References:
https://karaf.apache.org/
https://www.cve.org/CVERecord?id=CVE-2026-91085