Skip to content

write the file config store with owner-only permissions - #3411

Open
mrdevel2002-ui wants to merge 2 commits into
apache:mainfrom
mrdevel2002-ui:config-store-owner-only-perms
Open

mrdevel2002-ui wants to merge 2 commits into
apache:mainfrom
mrdevel2002-ui:config-store-owner-only-perms

Conversation

@mrdevel2002-ui

Copy link
Copy Markdown
Contributor

FileBasedConfigStore, the configStoreType: file backend behind tika-grpc component management and shared pipes workers, writes config-store.json through a sibling .tmp created with the process umask, and the atomic rename publishes those bits. Under the default 022 umask every saved fetcher and emitter config is therefore readable by any other local account, and that store is exactly where resolved credentials end up: S3 secretKey, HTTP password and jwtSecret, Azure sasToken, Graph clientSecret (the configuration docs note that a persistent store receives the resolved configurations). saveToFile now creates the .tmp as rw------- on POSIX filesystems before writing it, so the rename publishes an owner-only file; filesystems without POSIX permissions keep today's behavior. The new test in ConfigStoreTest saves credential-bearing configs through the store and asserts the file is owner-only with no .tmp left behind; it fails on main (GROUP_READ, OTHERS_READ present) and passes here, and clean install of tika-pipes-core (221 tests, checkstyle, spotless, forbidden-apis) is green.

There is no JIRA issue for this yet; I will open one and add the TIKA-XXXX prefix to the title and commit if you would like it tracked. I can add the ASF Generated-by: trailer to the commit if you prefer it there as well.

FileBasedConfigStore wrote config-store.json through a sibling .tmp file
which carry resolved credentials, were readable by every local user under
the default 022 umask. The .tmp is now created owner-only on POSIX
filesystems before it is written and atomically renamed into place.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Concurrent saves share a temporary pathname and can bypass the intended owner-only permissions.

1 open issue
What changed in this PR

This PR hardens the file-backed configuration store used by component management and shared pipes workers to protect persisted credentials from other local users.

Changes:

  • Creates temporary store files with owner-only permissions on POSIX filesystems, retaining existing behavior elsewhere.
  • Adds a regression test for saved-file permissions, temporary-file removal, and configuration reload.
File Description
tika-pipes/​tika-pipes-core/​src/​test/​java/​org/​apache/​tika/​pipes/​core/​config/​ConfigStoreTest.java Tests owner-only permissions and successful persistence.
tika-pipes/​tika-pipes-core/​src/​main/​java/​org/​apache/​tika/​pipes/​core/​config/​FileBasedConfigStore.java Applies owner-only permissions before writing and atomically replacing the store.

Review effort: Balanced

Comment on lines +162 to +164
Path tempFile = configFile.resolveSibling(configFile.getFileName() + ".tmp");
Files.deleteIfExists(tempFile);
Files.createFile(tempFile, ownerOnly());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point, synchronized only covers one instance, and a shared config-store.json.tmp lets a second writer pull the file out from under the first. Fixed in 62b05d1: each save now goes through Files.createTempFile in the store's directory with the owner-only attribute, so every writer gets its own name and nobody else deletes or recreates it. The temp file is also removed if the write or move fails. The test now checks that the directory holds nothing but config-store.json after the saves.

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.

2 participants