Bug 2465250 (CVE-2026-18157) - CVE-2026-18157 yggdrasil-worker-package-manager: yggdrasil-worker-package-manager: Remote Code Execution via APT Argument Injection
Summary: CVE-2026-18157 yggdrasil-worker-package-manager: yggdrasil-worker-package-man...
Keywords:
Status: NEW
Alias: CVE-2026-18157
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
high
high
Target Milestone: ---
Assignee: Product Security
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-05-04 14:54 UTC by OSIDB Bzimport
Modified: 2026-07-31 00:18 UTC (History)
3 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-05-04 14:54:31 UTC
AI_ONLY_REPORT
package: yggdrasil-worker-package-manager-0.2.3-4.el10
------
Summary: Remote Code Execution via APT Argument Injection:  
attacker-controlled package names beginning with `-` are passed to  
`apt-get` as raw arguments on Debian/Ubuntu code paths, allowing APT option  
injection and potentially root code execution through dangerous APT  
configuration directives for callers that can reach the worker dispatch  
boundary.
Requirements to exploit: The attacker must be able to dispatch  
package-manager requests to the worker over its configured D-Bus/dispatcher  
trust boundary on a Debian/Ubuntu deployment where the APT backend is  
selected. The `remove` path is directly reachable; the `install` path is  
also reachable when the configured `allow-pattern` permits the supplied  
name.
Component affected: `yggdrasil-worker-package-manager`, Debian/Ubuntu APT  
backend in `package_manager_apt.go` (`PackageManagerApt.run`), reached from  
message handling in `main.go` (`dataRx`)
Version affected: `yggdrasil-worker-package-manager-0.2.3-4.el10`, when  
this code is built or deployed on Debian/Ubuntu systems using the APT  
backend
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:N/S:U/C:H/I:H/A:H - 7.8 (HIGH)
AV:L - Exploitation requires access to the local D-Bus/dispatcher  
boundary used to send requests to the worker.
AC:L - A leading-hyphen package name is sufficient to trigger APT option  
parsing; no special race or environmental condition is required for the  
injection primitive.
PR:L - The caller must already be allowed to dispatch requests to this  
worker.
UI:N - No separate user interaction is required once the caller can  
invoke the worker.
S:U - The impact is within the same system security scope.
C:H - Successful abuse of root-executed APT configuration can expose all  
data available to the worker context.
I:H - Successful abuse can execute attacker-controlled actions as root  
and fully compromise system integrity.
A:H - Successful abuse can disrupt package management or broader system  
availability in the worker's root context.
Impact: Important. This issue can allow a caller that is authorized to use  
the worker interface to cross a trust boundary and influence a  
root-executed package-manager invocation, with high confidentiality,  
integrity, and availability consequences if dangerous APT options are  
accepted. It does not meet Critical because exploitation is not  
unauthenticated remote and depends on a restricted dispatch boundary and  
the Debian/Ubuntu APT code path.
Embargo: no
Reason: Exploitation depends on access to the configured worker  
dispatch boundary and the Debian/Ubuntu APT backend rather than  
unauthenticated remote reachability. The issue is serious, but the exposure  
is constrained enough that coordinated public fixing without embargo  
appears appropriate.
Acknowledgement: Aisle Research
Vulnerability Details: The APT backend invokes `apt-get` through  
`exec.Command`, so this is not shell injection. The security flaw is  
argument injection: untrusted `name` values are appended directly to the  
`apt-get` argument list without an option terminator (`--`) and without  
rejecting leading-hyphen values. As a result, a package name such as `-h`  
or `-o...` is interpreted by APT as an option rather than a package name.
```go
func (p *PackageManagerApt) run(
command string,
args ...string,
) (stdout, stderr []byte, code int, err error) {
cmdargs := []string{"--assume-yes", command}
cmdargs = append(cmdargs, args...)
cmd := exec.Command("/usr/bin/apt-get", cmdargs...)
stdout, stderr, code, err = run(cmd, p.sendStdout, p.sendStderr)
return
}
```
The message handling path forwards `remove` requests without any  
allow-pattern check, and `install` is only protected by the configured  
allow-patterns. With the default permissive configuration, both paths  
accept attacker-controlled names:
```go
case "install":
if !packageAllowed(m.Name) {
return fmt.Errorf("cannot install %v: does not match an allow pattern",  
m.Name)
}
outb, errb, code, err = pm.Install(m.Name)
case "remove":
outb, errb, code, err = pm.Uninstall(m.Name)
```
```toml
allow-pattern = [".*"]
```
A deterministic proof of the bug is that `{"command":"remove","name":"-h"}`  
causes APT help output instead of package removal behavior, showing that  
the attacker-controlled `name` is parsed as an APT option. That establishes  
the option-injection primitive. Escalation from this primitive to root  
command execution depends on which APT configuration directives are  
accepted for the chosen operation, so the exact RCE path is configuration-  
and behavior-dependent, but the trust-boundary violation is directly  
observable.
Steps to reproduce:
1. On a Debian/Ubuntu system with this worker installed, ensure the test  
caller has access to the configured dispatch boundary for the  
package-manager worker.
2. Dispatch a `remove` request with a leading-hyphen package name, for  
example:
```json
{"command":"remove","name":"-h"}
```
3. Send it using the normal worker dispatch mechanism, for example:
```sh
echo '{"command":"remove","name":"-h"}' | yggctl dispatch --worker  
package_manager -
```
4. Observe that the worker returns `apt-get` help output rather than  
attempting to remove a package. This confirms the injected `name` was  
interpreted as an APT option.
5. To test the broader impact, replace `-h` with a crafted `-o...` argument  
and verify whether the selected APT directive is honored for the invoked  
operation. The option-injection primitive is reproducible even where a  
specific hook-style command execution path is not demonstrated.
Mitigation: Do not allow untrusted callers to access this worker's dispatch  
boundary. On affected deployments, tighten `allow-pattern` values so  
package names cannot begin with `-`, and avoid relying on the `remove` path  
for untrusted input until validation is added. The APT backend should also  
terminate option parsing with `--` before forwarding package names.
Proposed Fix: Reject empty or leading-hyphen package names before invoking  
`apt-get`, and insert `--` so subsequent arguments are treated only as  
package names. As additional hardening, consider applying the same  
allow-pattern policy to `remove` that is already used for `install`.
```diff
diff --git a/package_manager_apt.go b/package_manager_apt.go
— a/package_manager_apt.go
+++ b/package_manager_apt.go
@@
func (p *PackageManagerApt) run(
command string,
args ...string,
) (stdout, stderr []byte, code int, err error) {
+	for _, a := range args {
+		if len(a) == 0 || a[0] == '-' {
+			return nil, nil, -1, fmt.Errorf("invalid package name: %q", a)
+		}
+	}
cmdargs := []string{"-assume-yes", command}
+	cmdargs := []string{"--assume-yes", command, "--"}
cmdargs = append(cmdargs, args...)
cmd := exec.Command("/usr/bin/apt-get", cmdargs...)
stdout, stderr, code, err = run(cmd, p.sendStdout, p.sendStderr)
return
}
```
------
This report was generated using AI technology. Always review AI-generated  
content prior to use

Comment 1 Christopher Lusk 2026-06-26 17:56:31 UTC
Tracker filed for rhel-10.3: https://issues.redhat.com/browse/RHEL-189261


Note You need to log in before you can comment on or make changes to this bug.