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

CVE-2026-91012 Apache Karaf 路径遍历漏洞

影响具备 manager 角色的用户可向任意可写路径写入任意文件,可能导致权限提升或代码执行

AI 研判

Apache Karaf 的 ConfigRepositoryImpl#update 方法在处理配置更新时,未校验由调用方提供的输入所推导出的目标文件路径是否位于 ${karaf.etc} 目录内。攻击者可通过 felix.fileinstall.filename 属性或包含 ".." 的 PID 构造路径穿越,将任意内容写入 Karaf 进程可写的任意文件。

影响范围

Apache Karaf

Apache Karaf 中 org.apache.karaf.config.core.impl.ConfigRepositoryImpl 相关实现,具体受影响版本范围暂无公开信息。

漏洞详情

该漏洞属于路径穿越/任意文件写入。当提交的属性映射包含 felix.fileinstall.filename 时,其值被直接转换为 File 对象,可指向任意绝对路径;否则配置 PID 会被原样拼接进文件名,含 ".." 的 PID 可逃逸出 ${karaf.etc}。createFactoryConfiguration() 通过 factory PID/别名存在同样问题。

利用条件与风险

利用前提是攻击者已持有 Karaf 的 manager 角色(该角色在默认 ACL 中即可执行 config:update)。实战中可借此覆盖 users.properties、ACL 配置或管理配置等本应仅 admin 可写的文件,从而实现权限提升。

修复建议

官方修复方案暂无公开信息;临时缓解措施包括限制 manager 角色对 config:* 命令与 config MBean 的访问,或对提交的 PID 与 felix.fileinstall.filename 值进行路径规范化与目录边界校验。

原始情报

org.apache.karaf.config.core.impl.ConfigRepositoryImpl#update(pid, properties),
which backs the “config” MBean and the config:* shell commands, derives the file
it writes a configuration to from caller-supplied input without checking that
the result stays inside ${karaf.etc}:

* if the submitted property map contains a felix.fileinstall.filename entry, that value is turned directly into a File (getCfgFileFromProperty), so it can point to any absolute path the Karaf process can write to;
* otherwise the configuration PID is concatenated verbatim into the target file name (generateConfigFilename(): new File(karaf.etc, pid + “.cfg”)), so a PID containing “..” segments resolves outside ${karaf.etc}. createFactoryConfiguration() has the same issue via the factory PID/alias.

Both code paths are reachable by any caller holding the “manager” role under Karaf’s shipped command/JMX ACL (org.apache.karaf.command.acl.conf.cfg: “update = manager”). Such a user can therefore write attacker-controlled content to any file the Karaf process can write, including files the same ACL otherwise reserves to “admin” (etc/users.properties, etc/*.acl.*.cfg, etc/org.apache.karaf.management.cfg, and similar), allowing a manager-role user to grant themselves the admin role or otherwise take over the container.

ConfigMBeanImpl.install() and the config:install shell command already guarded the equivalent risk on their own code path with a finalname.contains(“..”) string check, but that check does not stop absolute paths or symlink-based escapes, and it was never applied to ConfigRepositoryImpl.update() / createFactoryConfiguration() at all.