天下漏洞,尽知其名
HIGH 重点关注

CVE-2026-91085 Apache Karaf 权限绕过漏洞

影响低权限认证用户可向配置目录写入任意文件,可能导致敏感信息泄露或配置篡改

AI 研判

Apache Karaf 的 shell/SSH 命令安全依赖按 scope 划分的 ACL 配置文件。当某条命令没有匹配到任何 ACL 规则时,SecuredSessionFactoryImpl.checkSecurity() 会默认放行(fail open),而用于兜底强制角色的 karaf.secured.command.compulsory.roles 在 system.properties 中默认被注释掉。随发行版提供的 config scope ACL 缺少 install 条目,导致 config:install 命令对任意已认证用户开放。

影响范围

Apache Karaf

Apache Karaf 使用默认 ACL 配置的版本(config scope ACL 未包含 install 条目、且 compulsory.roles 未启用)。具体受影响版本范围暂无公开信息。

漏洞详情

漏洞类型为访问控制缺失(ACL 规则遗漏导致的越权)。成因是 ACL 解析器在 NO_MATCH 时设置 passCheck=true 的 fail-open 设计,加上 config:install 未被任何规则覆盖,且强制角色开关默认关闭。利用方式是任意已认证用户(包括仅有 viewer 角色者)执行 config:install <url> <finalname>,从远程拉取内容并写入 ${karaf.etc} 目录。

利用条件与风险

利用前提是攻击者已获得任意有效账号(含最低权限的 viewer)。实战中可借此写入配置文件,可能篡改服务行为或植入恶意配置,风险较高。

修复建议

官方修复方案暂无公开信息。临时缓解措施:在 etc/system.properties 中启用 karaf.secured.command.compulsory.roles 设置强制角色,并在 config scope ACL 中为 install 命令显式添加角色限制。

原始情报

Apache Karaf’s shell/SSH command security is enforced by per-scope ACL configuration files (etc/org.apache.karaf.command.acl..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  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.