Skip to content

Ensure configuration files are always written within ${karaf.etc} - #2867

Open
jbonofre wants to merge 1 commit into
apache:mainfrom
jbonofre:config-etc-path-containment
Open

Ensure configuration files are always written within ${karaf.etc}#2867
jbonofre wants to merge 1 commit into
apache:mainfrom
jbonofre:config-etc-path-containment

Conversation

@jbonofre

@jbonofre jbonofre commented Sep 8, 2026

Copy link
Copy Markdown
Member

Motivation

ConfigRepositoryImpl builds the file it persists a configuration to from caller-supplied input and never checks that the result stays inside ${karaf.etc}:

  • a felix.fileinstall.filename entry in the property map is turned into a File as-is (getCfgFileFromProperty), so it can point anywhere;
  • the PID (and the factory alias) are concatenated verbatim into the file name (generateConfigFilename, createFactoryConfiguration), so a name containing .. segments resolves outside the folder.

These paths are reachable from the config MBean and the config:* shell commands. ConfigMBeanImpl.install() and the config:install command already tried to guard against this, but only with a finalname.contains("..") string test, which does not cover absolute paths or symlinks.

Changes

  • New org.apache.karaf.util.PathUtils with isWithin(parent, child) / checkWithin(parent, child), doing an element-wise startsWith comparison on canonical paths.
  • ConfigRepositoryImpl.update() and createFactoryConfiguration() now verify the target file is inside ${karaf.etc} before writing. The branch that reuses an already-persisted felix.fileinstall.filename coming from Configuration Admin is left untouched so multi-directory Felix FileInstall setups keep working.
  • ConfigMBeanImpl.install() and InstallCommand (config:install) use PathUtils.checkWithin(...) instead of the contains("..") check.
  • Tests: PathUtilsTest, ConfigRepositoryImplContainmentTest. ConfigMBeanImplTest.testInstallWithNonAuthorizePath now expects MBeanException (the rejection is raised inside the method's existing try).

ConfigRepositoryImpl derived the target file from caller-supplied input
(the felix.fileinstall.filename property and the PID / factory alias used
to build the file name) without checking that the result stayed inside
${karaf.etc}. Add a canonical-path containment check, shared through a new
org.apache.karaf.util.PathUtils helper, and reuse it in
ConfigMBeanImpl.install() and the config:install command in place of the
weaker finalname.contains("..") string check.
@jbonofre
jbonofre force-pushed the config-etc-path-containment branch 2 times, most recently from 83d9181 to d138329 Compare September 8, 2026 17:47
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

Test Results

  711 files  + 6    711 suites  +6   1h 19m 43s ⏱️ + 1m 56s
  954 tests + 8    906 ✅ + 8   48 💤 ±0  0 ❌ ±0 
2 862 runs  +24  2 718 ✅ +24  144 💤 ±0  0 ❌ ±0 

Results for commit d138329. ± Comparison against base commit 6e40475.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant