Skip to content

fix: the config cache is restricted to its owner - #883

Merged
blaipr merged 1 commit into
mainfrom
fix/the-config-cache-is-restricted-to-its-owner
Aug 26, 2026
Merged

fix: the config cache is restricted to its owner#883
blaipr merged 1 commit into
mainfrom
fix/the-config-cache-is-restricted-to-its-owner

Conversation

@blaipr

@blaipr blaipr commented Aug 26, 2026

Copy link
Copy Markdown
Member

var/cache/config.cache is a serialized ConfigData. That carries the database password,
the mail password, the LDAP bind password and the password salt — the same material as
config.xml, whose directory ConfigUtil::checkConfigDir() deliberately pins to 0750 for
exactly that reason. The cache was left at whatever the umask gave it, measured at 0644 in
the running container, so on a shared host every local account could read the
installation's credentials out of it.

It is written 0600 now, which is what the backup archives already do and for the same
stated reason.

I also had the cache directory held at 0750, matching the config directory, and backed
that out. It works — verified going 755 to 750 on a live request — but var/cache/.blank
is a tracked file and the directory is owned by the web user, so host-side git
immediately failed with lstat("var/cache/.blank"): Permission denied and refused to
operate. Fine in production, not fine for anyone working in the repository, and plausibly
not fine in CI.

That leaves the compiled DI containers, which php-di writes 0666 in its own library code
(@chmod($tmpFile, 0666) in Compiler.php) and which are PHP executed on every request.
Restricting the directory was what would have covered those, since we do not control how
php-di writes them. It wants a deployment answer — ownership and umask on var/cache
rather than an application chmod, and is recorded here rather than half-fixed.

Checked by dropping the chmod: the save test fails.

`var/cache/config.cache` is a serialized ConfigData. That carries the database password,
the mail password, the LDAP bind password and the password salt — the same material as
`config.xml`, whose directory `ConfigUtil::checkConfigDir()` deliberately pins to 0750 for
exactly that reason. The cache was left at whatever the umask gave it, measured at 0644 in
the running container, so on a shared host every local account could read the
installation's credentials out of it.

It is written 0600 now, which is what the backup archives already do and for the same
stated reason.

I also had the cache *directory* held at 0750, matching the config directory, and backed
that out. It works — verified going 755 to 750 on a live request — but `var/cache/.blank`
is a tracked file and the directory is owned by the web user, so host-side git
immediately failed with `lstat("var/cache/.blank"): Permission denied` and refused to
operate. Fine in production, not fine for anyone working in the repository, and plausibly
not fine in CI.

That leaves the compiled DI containers, which php-di writes 0666 in its own library code
(`@chmod($tmpFile, 0666)` in Compiler.php) and which are PHP executed on every request.
Restricting the directory was what would have covered those, since we do not control how
php-di writes them. It wants a deployment answer — ownership and umask on `var/cache` —
rather than an application chmod, and is recorded here rather than half-fixed.

Checked by dropping the chmod: the save test fails.
@blaipr
blaipr merged commit 6bfe3b4 into main Aug 26, 2026
8 checks passed
@blaipr
blaipr deleted the fix/the-config-cache-is-restricted-to-its-owner branch August 26, 2026 19:39
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