Security advisory: local privilege escalation in the fcgiwrap NixOS module (also affecting the cgit, smokeping, and zoneminder modules)

Summary

A combination of issues has been identified in the NixOS fcgiwrap module
(services.fcgiwrap.*), permitting Local Privilege Escalations when the module
is enabled (directly or indirecty through other modules).

The issue stems from the previous use of a global shared instance of fcgiwrap
with loose permissions to accomodate multiple consumer modules.

Am I affected?

You are most likely affected if your NixOS configuration is making use of:

  • services.fcgiwrap.*, or
  • services.cgit.*, or
  • services.smokeping.*, or
  • services.zoneminder.*.

The user as which fcgiwrap and its scripts are spawned can be obtained with:
systemctl show -pUser fcgiwrap.service. An empty value means root.

The permissions of the fcgiwrap control socket can be obtained with:
ls -l /run/fcgiwrap.sock. World readable+writable means any local user can
run scripts as the fcgiwrap user previously shown.

Remediation

Remediating the issue is done by:

  1. updating the NixOS channels, then
  2. migrating and adjusting insecure options in the user configuration, then
  3. adjusting permissions and ownership of existing state and cache files.

The necessary module changes are being integrated into nixpkgs and made
available through the usual update channels:

Specific instructions follow.

services.fcgiwrap.*

Users of the services.fcgiwrap.* options should migrate to
services.fcgiwrap.instances.*, setting proper process and socket permissions.

The problematic former set of options has been deprecated in NixOS 24.05 and
removed for 24.11. (The security error can be temporarily bypassed on 24.05
with services.fcgiwrap.allowGlobalInstanceLocalPrivilegeEscalation.)

Manual intervention is also required to align the ownership and permissions of
state files accessed by the CGI scripts, varying on setups.

services.cgit.*

The cgit NixOS module has been internally migrated to use independent isolated
instances of fcgiwrap instead of sharing the global insecure one.

Users of the services.cgit.* options now can and should set distinct
unprivileged users for cgit instances with services.cgit.*.{user,group}.
These default to “root” on NixOS 24.05 to avoid breaking existing setups, but
will default to the unprivileged “cgit” user in 24.11.

Manual intervention is required to ensure proper ownership and permissions
of the served git repositories. For shared repositories, see also
git-config(1): core.sharedRepository. Write permission for the chosen cgit
user is required by the git-http-backend used by the cgit module.

Cache files in /var/cache/cgit should be cleared as well.

services.smokeping.*

The SmokePing NixOS module has been internally migrated to use an independent
isolated instance of fcgiwrap instead of sharing the global insecure one.

Users of services.smokeping.* do not require configuration changes after
updating on 24.05 or 24.11.

Cache files located at /var/lib/smokeping should nevertheless be cleared.

services.zoneminder.*

The ZoneMinder NixOS module has been internally migrated to use an independent
isolated instance of fcgiwrap instead of sharing the global insecure one.

Users of services.zoneminder.* do not require configuration changes after
updating on 24.05 or 24.11.

Cache files located at /var/cache/zoneminder should nevertheless be cleared.

Relevant changes

9 Likes