Skip to main content
Vulnerability Database/CVE-2026-63349

CVE-2026-63349: AnyIO Privilege Escalation Vulnerability

CVE-2026-63349 is a privilege escalation vulnerability in AnyIO asynchronous framework where subprocess helpers fail to properly clear inherited supplementary groups. This article covers technical details, affected versions, security impact, and mitigation strategies.

Published:

CVE-2026-63349 Overview

CVE-2026-63349 affects AnyIO, a high-level asynchronous concurrency and networking framework layered on top of Trio or asyncio. In version 4.14.0, anyio.open_process() and anyio.run_process() accept the POSIX extra_groups argument but forward the value of the group argument to the backend instead. Callers that pass extra_groups=[] to clear inherited supplementary groups instead launch child processes that retain the parent process groups. This undermines a privilege-dropping boundary in POSIX applications relying on AnyIO subprocess helpers to spawn less-privileged children. The issue is categorized under [CWE-266] Incorrect Privilege Assignment.

Critical Impact

Child processes intended to run with reduced supplementary group membership inherit the parent's groups, defeating an explicit privilege-dropping control.

Affected Products

  • AnyIO version 4.14.0
  • AnyIO version 4.14.1
  • POSIX applications using anyio.open_process() or anyio.run_process() with extra_groups

Discovery Timeline

  • 2026-09-18 - CVE-2026-63349 published to NVD
  • 2026-09-25 - Last updated in NVD database

Technical Details for CVE-2026-63349

Vulnerability Analysis

AnyIO exposes POSIX subprocess options including group and extra_groups, mirroring the semantics of subprocess.Popen. The group argument sets the effective GID of the child, while extra_groups sets the list of supplementary group IDs. Passing extra_groups=[] is the canonical method to strip inherited supplementary groups before executing a less-privileged child. In AnyIO 4.14.0, the internal subprocess helper assigns kwargs["extra_groups"] = group, forwarding the wrong variable to the backend. The child therefore inherits the parent's supplementary groups regardless of what the caller supplied.

A secondary failure mode occurs when both group and extra_groups are provided. The integer value of group is passed where the backend expects an iterable of GIDs, causing a TypeError at launch. This makes affected code paths either silently insecure or noisily broken, depending on caller usage.

Root Cause

The defect is a one-line variable substitution error in src/anyio/_core/_subprocesses.py. The branch that handles extra_groups is not None sets the keyword argument using the group variable instead of extra_groups. The patched code corrects the assignment:

python
         kwargs["group"] = group
 
     if extra_groups is not None:
-        kwargs["extra_groups"] = group
+        kwargs["extra_groups"] = extra_groups
 
     if umask >= 0:
         kwargs["umask"] = umask

Source: AnyIO commit eb562e6

Attack Vector

Exploitation requires local access with elevated privileges that the application intends to drop. A privileged parent process using AnyIO subprocess helpers to launch a worker with reduced group membership will instead spawn that worker with the parent's supplementary groups. Any resource whose access control depends on group membership becomes reachable by the child, including files, sockets, and IPC endpoints. This is a passive privilege-boundary failure rather than an active injection primitive.

Detection Methods for CVE-2026-63349

Indicators of Compromise

  • Child processes spawned by AnyIO-based applications showing supplementary GIDs matching the parent process
  • TypeError exceptions raised from anyio.open_process() or anyio.run_process() calls that supply both group and extra_groups
  • Access to group-restricted files or sockets by processes that should have dropped supplementary groups

Detection Strategies

  • Audit Python dependency manifests for anyio==4.14.0 or anyio==4.14.1 using SBOM tooling or pip list output
  • Statically scan source code for calls to anyio.open_process or anyio.run_process that pass the extra_groups keyword
  • Compare child process supplementary group lists against expected post-drop values using /proc/<pid>/status (Groups: field)

Monitoring Recommendations

  • Log subprocess launches from privileged services and record the resulting UID, GID, and supplementary group set
  • Alert on unexpected group membership in processes launched by services running as root or another privileged account
  • Track exceptions from AnyIO subprocess helpers in application logs to surface the TypeError failure mode

How to Mitigate CVE-2026-63349

Immediate Actions Required

  • Upgrade AnyIO to version 4.14.2 or later in all affected environments
  • Inventory applications using anyio.open_process() and anyio.run_process() with the extra_groups argument
  • Review privileged services that rely on AnyIO to spawn less-privileged children and validate the resulting group membership

Patch Information

The fix is included in AnyIO 4.14.2. The correction is a single-line change in src/anyio/_core/_subprocesses.py that forwards the extra_groups value rather than group. See AnyIO Release 4.14.2, GHSA-3w57-8xmc-8v26, and the pull request discussion for full context.

Workarounds

  • Drop supplementary groups directly with os.setgroups([]) in a preexec_fn passed to the subprocess call, bypassing the broken AnyIO path
  • Pin AnyIO to a version prior to 4.14.0 that does not expose the affected code path if 4.14.2 cannot be deployed immediately
  • Wrap subprocess launches in a helper that verifies the child's /proc/<pid>/status group set matches the intended values before allowing further execution
bash
# Configuration example: upgrade AnyIO to the patched release
pip install --upgrade 'anyio>=4.14.2'

# Verify installed version
python -c "import anyio; print(anyio.__version__)"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.