Bug 2569357 (CVE-2026-125672)
| Summary: | CVE-2026-125672 cockpit: cockpit-storaged: Tang keyserver address from an untrusted LUKS header clevis token reaches curl's argument vector as an option | ||
|---|---|---|---|
| Product: | [Other] Security Response | Reporter: | OSIDB Bzimport <bzimport> |
| Component: | vulnerability | Assignee: | Product Security <prodsec-ir-bot> |
| Status: | NEW --- | QA Contact: | |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | unspecified | CC: | rhel-process-autobot, watson-tool-maintainers |
| Target Milestone: | --- | Keywords: | Security |
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | --- | |
| Doc Text: |
A flaw was found in cockpit-storaged. A Tang keyserver address read from a clevis token in a LUKS header is concatenated into curl's argument vector without a "--" separator. An address beginning with "-" is parsed by curl as an option instead of a hostname, allowing an attacker who can attach a crafted LUKS/clevis block device (for example, a local unprivileged user with an active console or desktop login session) to have an administratively-privileged Cockpit user unknowingly trigger curl option injection when editing the device's Tang keyserver settings. This can lead to arbitrary file read or write as the Cockpit session user.
|
Story Points: | --- |
| Clone Of: | Environment: | ||
| Last Closed: | Type: | --- | |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
A flaw was found in cockpit. The cockpit-storaged module's get_tang_adv() function (pkg/storaged/crypto/tang.jsx) builds curl's argument vector by string concatenation: cockpit.spawn(["curl", "-sSf", url + "/adv"]), with no "--" separator between options and the positional argument. On the Edit-Tang-keyserver path, this url value is read verbatim from a clevis token embedded in the LUKS header of a block device, which is data controlled by whoever can write to or attach that device, not necessarily the Cockpit operator. validate_url() only rejects empty strings and values that fail JavaScript URL parsing; a value such as "-K/var/tmp/stash" parses successfully (hostname "-k") and is accepted. When such a value reaches curl, curl interprets it as the "-K" (config file) option instead of a hostname, loading an attacker-planted curl configuration file. The planted configuration can set "output" to any path the Cockpit session user can write, "url" to a file:// URL to read any file that user can read, or "upload-file" with a remote destination to exfiltrate data -- all running as the Cockpit session user (not root; the LUKS-header read itself runs with superuser privileges via python.spawn(..., {superuser: "require"}), but the subsequent curl invocation does not). A local unprivileged user with a local, active console or desktop login session (not a remote SSH or Cockpit web session) can plant the malicious LUKS header using the standard, default-granted udisks2 org.freedesktop.udisks2.loop-setup polkit permission (allow_active=yes), requiring no elevated privilege. An administrator with Cockpit access who then opens the "Edit Tang keyserver" dialog for that device and clicks Save, without recognizing the prefilled value as a curl option rather than an address, triggers the chain. No non-default configuration is required.