Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: cockpit-356-1.el10 ------ Summary: Privileged Symlink Dereference in `pkg/users/ssh-add-public-key.sh` Allows Arbitrary Ownership/Mode Changes: the privileged add-key helper follows attacker-controlled `.ssh` and `authorized_keys` symlinks, allowing attacker-chosen ownership changes and related mode changes when the helper runs with an active privileged bridge/root context. Requirements to exploit: A local authenticated user must be able to control the target account's home directory contents and must get the helper to run with elevated privileges, such as in an active privileged Cockpit session. The issue is not arbitrary `home_dir` injection; it arises from symlink manipulation inside the configured home path. Without a privileged bridge/root context, the same code path does not cross a security boundary. Component affected: `cockpit-356-1.el10` Users "Add public key" helper, `pkg/users/ssh-add-public-key.sh`, invoked from `pkg/users/authorized-keys.js` Version affected: `cockpit-356-1.el10` when the Users "Add public key" workflow is executed with an active privileged bridge/root context Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H - 7.8 (HIGH) AV:L - The attacker needs a local authenticated account whose home directory contents they can control. AC:L - Preparing the required symlink state is straightforward and does not require races or special timing. PR:L - Low privileges are sufficient before exploitation. UI:R - The vulnerable add-key action must be invoked in a session where the helper actually has privileged/root execution context. S:U - The vulnerable component and the impacted resources are under the same host security authority. C:H - Redirected privileged file handling can expose protected files or make them accessible to the attacker. I:H - Attacker-chosen ownership changes on sensitive paths can directly break privilege boundaries and enable further unauthorized modification. A:H - Ownership or mode changes on critical paths can disrupt services or system operation. Impact: Important. Based on Red Hat's severity guidance, this issue can allow a local authenticated user to gain additional privileges by redirecting privileged filesystem operations to attacker-chosen paths. That is a direct integrity boundary break with potentially severe confidentiality and availability consequences once triggered. It is not Critical because exploitation is not remote or unauthenticated and requires both user interaction and a privileged execution context. Embargo: yes Reason: The issue provides a straightforward local privilege-escalation technique when the affected workflow is used in a privileged session, and there is no released fix yet. Acknowledgement: Aisle Research Vulnerability Details: The helper script performs privileged operations in `$2/.ssh` without checking whether `.ssh` or `authorized_keys` are symlinks: ```sh mkdir -p "$2/.ssh" cd "$2/.ssh" chown $1 . touch authorized_keys 2> /dev/null || true chown $1 authorized_keys 2> /dev/null || true sed -i -e '$a\' authorized_keys cat >> authorized_keys chown $1 authorized_keys 2> /dev/null || true chmod 600 authorized_keys ``` The Users page reaches this helper through `cockpit.script(adder, [user_name, home_dir], { superuser: "try", err: "message" })`, and the add-key action is exposed when `user == current_user | !!superuser.allowed`. The `home_dir` value comes from the account record, so the problem is not arbitrary path input from the UI; it is privileged dereference of attacker-controlled symlinks inside the configured home path. If `.ssh` is a symlink to an attacker-chosen directory, `cd "$2/.ssh"` and `chown $1 .` operate on the symlink target directory and can change its ownership under elevated privileges. Subsequent `touch`, `chown`, and `chmod` operations then act within that dereferenced location. An `authorized_keys` symlink can also influence file handling in that directory, although the exact final file state depends on how the underlying utilities handle in-place edits. The core issue is that privileged filesystem changes are performed on attacker-controlled paths without rejecting symlinks. Steps to reproduce: The following reproducer demonstrates the deterministic directory-ownership change through a symlinked `.ssh` directory without relying on tool-specific in-place editing behavior. 1. Prepare a safe victim path and an attacker-controlled home directory: ```bash sudo rm -rf /tmp/ssh-poc-home /tmp/ssh-poc-target sudo mkdir -p /tmp/ssh-poc-home /tmp/ssh-poc-target sudo chown root:root /tmp/ssh-poc-target ln -s /tmp/ssh-poc-target /tmp/ssh-poc-home/.ssh ``` 2. Confirm the initial owner: ```bash stat -c '%U:%G %n' /tmp/ssh-poc-target ``` 3. Run the helper as root with a benign test key: ```bash printf 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAITestKeyForPoC\n' | \ sudo /bin/sh pkg/users/ssh-add-public-key.sh nobody /tmp/ssh-poc-home ``` 4. Check the target directory again: ```bash stat -c '%U:%G %n' /tmp/ssh-poc-target ``` Expected result: the owner of `/tmp/ssh-poc-target` changes from `root` to `nobody`, demonstrating that the privileged helper followed the attacker's `.ssh` symlink and applied `chown` to the target directory. Mitigation: Until a fix is available, avoid using the Users "Add public key" workflow in a privileged session for untrusted accounts, and verify that the target account's `.ssh` directory and `authorized_keys` path are not symlinks before using the feature. Administratively managed `.ssh` contents that are not attacker-controlled reduce exposure. Proposed Fix: A minimal hardening change is to reject symlinked `.ssh` and `authorized_keys` paths before performing privileged filesystem operations, canonicalize the working directory with `cd -P`, and use `chown -h` defensively. ```diff — a/pkg/users/ssh-add-public-key.sh +++ b/pkg/users/ssh-add-public-key.sh @@ set -euf -mkdir -p "$2/.ssh" -cd "$2/.ssh" +user="$1" +home="$2" +ssh_dir="$home/.ssh" + +mkdir -p – "$ssh_dir" +[ -d "$ssh_dir" ] || { echo "Invalid .ssh directory: $ssh_dir" >&2; exit 1; } +[ -L "$ssh_dir" ] && { echo "Refusing symlinked .ssh directory: $ssh_dir" >&2; exit 1; } +cd -P – "$ssh_dir" -chown $1 . +[ -e authorized_keys ] && [ -L authorized_keys ] && { + echo "Refusing symlinked authorized_keys" >&2 + exit 1 +} touch authorized_keys 2> /dev/null || true -chown $1 authorized_keys 2> /dev/null || true +[ -L authorized_keys ] && { + echo "Refusing symlinked authorized_keys" >&2 + exit 1 +} +chown -h "$user" . +chown -h "$user" authorized_keys 2> /dev/null || true sed -i -e '$a\' authorized_keys cat >> authorized_keys -chown $1 authorized_keys 2> /dev/null || true +chown -h "$user" authorized_keys 2> /dev/null || true chmod 600 authorized_keys ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use
Fixed upstream in version 372: https://github.com/cockpit-project/cockpit/releases/tag/372 Upstream commit: https://github.com/cockpit-project/cockpit/commit/4796b28be064a90e32262cec85be7839e6198e23