May 6, 2026·7 min read·15 visits
Canonical authd incorrectly overwrites custom user GIDs with their UID during identity syncs. This logic flaw permits local privilege escalation via group collision and causes denial of service through incorrect file ownership.
Canonical authd versions prior to 0.6.4 contain a local privilege escalation and denial of service vulnerability stemming from a logic error in primary group ID (GID) assignment. The daemon improperly overwrites intentional administrative GID configurations during identity provider synchronization events.
Canonical's authd operates as an authentication daemon responsible for integrating external identity providers with local system accounts. It manages user sessions, attributes, and group assignments upon login. The daemon relies on local databases to cache identity information and ensure consistent access controls across system reboots and administrative actions.
CVE-2026-6970 identifies a logic error within the daemon's user synchronization mechanism, specifically classified as CWE-842: Placement of User into Incorrect Group. During identity provider updates, the daemon re-evaluates user attributes and attempts to enforce consistency between the remote identity and local system states. A flaw in this synchronization logic causes the daemon to discard explicitly configured group ID (GID) settings.
The vulnerability manifests under specific administrative conditions. Accounts provisioned by authd versions prior to 0.5.4, or accounts where an administrator explicitly modified the primary group using the authctl group set-gid command, are susceptible. In these scenarios, the user's intended primary GID diverges from their standard user ID (UID).
The overarching impact encompasses both Denial of Service (DoS) and Local Privilege Escalation (LPE). The denial of service occurs when applications fail to read or write files because newly created assets are assigned the incorrect group ownership. The privilege escalation vector arises if the enforced UID-based GID collides with an existing, privileged system group.
The root cause resides in the UpdateUser function located within internal/users/manager.go. This routine executes whenever the daemon synchronizes a local account record with upstream identity provider data. Its primary role is to ensure local system artifacts reflect the current state of the external identity.
Prior to the patch, authd operated under the strict assumption that every user account utilized a User Private Group (UPG) model. In a standard UPG implementation, the system creates a dedicated primary group for every new user, and this group's GID strictly matches the user's UID. The code enforced this assumption programmatically.
The specific failure mechanism involved an unconditional assignment operation. Regardless of the current database state or any prior administrative overrides, the UpdateUser function executed the statement userPrivateGroup.GID = &u.UID. This instruction forced the user's session primary group to reset to their UID.
This logic entirely ignored manual configurations implemented via the authctl group set-gid command. Consequently, an administrator's intent to place a user within a shared organizational group as their primary GID was silently subverted upon the next identity synchronization. The user's active session would then operate with the reverted, UID-based group identity.
An analysis of the vulnerable internal/users/manager.go file demonstrates the improper state enforcement. The original code contained a direct, unconditional pointer assignment that prioritized the user's UID over any existing group configuration.
// Pre-patch code snippet
// User private Group GID is the same of the user UID.
userPrivateGroup.GID = &u.UIDThe fix, introduced in commit 154b428305cb1a7a19c897626fefd09d6dde8b9f, replaces this rigid assignment with conditional initialization logic. The patched code verifies the existence of the group record before applying default assumptions.
// Post-patch code snippet
if g.GID == nil {
// The group does not exist in the database.
if g == userPrivateGroup {
// On first login the user private group doesn't exist yet, so we default to GID = UID.
g.GID = &u.UID
} else {
// Else, add it to the list of new groups to create.
newGroups = append(newGroups, *g)
continue
}
}The revised logic ensures that the GID assignment only defaults to the UID during the initial login event when g.GID is explicitly nil. Subsequent updates bypass this assignment block, preserving the existing GID state stored in the daemon's internal database. This mitigates the overwrite condition and honors manual authctl configurations.
Exploitation of CVE-2026-6970 requires local system access and specific prerequisite configurations. The attacker must possess an active, low-privileged account on the target system. Furthermore, this account must have been previously modified by a system administrator to utilize a custom primary GID.
The attack sequence is passive or semi-active. The attacker must trigger or await an identity provider synchronization event. Depending on the environment configuration, this sync may occur automatically upon login, after a predefined timeout, or it can be forced if the attacker has the ability to manipulate the local authd cache or trigger an external identity token refresh.
Once the UpdateUser routine processes the synchronization, the local user's active session is updated. The user's primary GID is stripped of its administrative assignment and forcibly reverted to match their UID. From this point forward, any files, directories, or processes initiated by the attacker inherit this incorrect group context.
The local privilege escalation payload is realized if the attacker's UID maps to the GID of a privileged system group. For example, if the attacker's UID is 1001, and GID 1001 happens to be assigned to a sensitive operational group on the local machine, the attacker's newly created files are owned by that operational group. This can facilitate unauthorized data access or the manipulation of shared system resources.
The vulnerability carries a CVSS v4.0 score of 7.3, reflecting its classification as a High severity issue. The vector string CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N details the risk profile. The attack vector is strictly Local (AV:L), and privileges required are Low (PR:L), necessitating base system access.
The attack complexity is Low (AC:L), but the attack requirements are Present (AT:P). This reflects the need for a specific, pre-existing administrative configuration. The system must possess accounts with explicitly modified GIDs or legacy accounts from earlier authd deployments. Without these conditions, the forced UID-to-GID mapping behaves as a standard User Private Group setup and yields no security boundary violation.
The impact metrics for Confidentiality, Integrity, and Availability are all designated as High. File ownership corruption directly degrades system availability by preventing legitimate services from interacting with newly created files. Furthermore, if a group collision occurs, attackers gain high-impact read and write capabilities over files governed by the colliding group, breaking confidentiality and integrity boundaries.
Despite the severe technical impact, the immediate threat landscape is constrained. The Exploit Prediction Scoring System (EPSS) score is 0.00015, translating to a 0.01% probability of exploitation within 30 days. No public proof-of-concept exploits or active campaigns utilize this vulnerability.
The definitive remediation for CVE-2026-6970 requires updating the Canonical authd package to a patched version. Upstream users must deploy authd version 0.6.4. Ubuntu system administrators must install the security update designated 0.6.1ubuntu0.1 as distributed via USN-8212-1.
Following the application of the patch, administrators must perform a system state audit to identify any lingering discrepancies. Executing standard queries such as getent passwd and getent group will reveal users whose current primary GID differs from their intended administrative assignment. Any detected anomalies should be manually corrected using authctl group set-gid.
Administrators should also conduct a file system review within shared directories to locate orphaned or incorrectly permissioned assets. Files created by users during the vulnerable synchronization periods will retain the incorrect GID ownership even after the authd package is updated. Standard find commands targeting mismatched UID/GID combinations are necessary to restore proper access control lists.
For environments unable to immediately deploy the patch, there are no robust direct workarounds that preserve external identity synchronization. Administrators must assume that custom GID assignments are volatile and monitor file ownership rigorously until patching is complete.
CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
authd Canonical | < 0.6.4 | 0.6.4 |
authd Canonical | = 0.6.0 | 0.6.1ubuntu0.1 |
authd Canonical | >= 0.6.1, < 0.6.1ubuntu0.1 | 0.6.1ubuntu0.1 |
| Attribute | Detail |
|---|---|
| CVE ID | CVE-2026-6970 |
| CVSS v4.0 | 7.3 (High) |
| Attack Vector | Local (AV:L) |
| EPSS Score | 0.00015 (2.93%) |
| CWE ID | CWE-842 |
| Impact | Local Privilege Escalation, Denial of Service |
| Exploit Status | None |
| KEV Status | Not Listed |
The system places a user into an incorrect group or role.
An information disclosure vulnerability in Open WebUI versions 0.10.2 and earlier allows authenticated non-admin users with read-only access (or any authenticated user when a tool is shared publicly) to retrieve the raw Python source code of custom workspace tools. Because these server-side tools commonly contain hardcoded API tokens, credentials, and proprietary logic, the exposure of raw tool source code severely compromises confidentiality and can facilitate wider infrastructure compromise.
CVE-2026-70492 (also tracked as GHSA-pwxh-7358-jq2x) is a stored Cross-Site Scripting (XSS) vulnerability in Open WebUI versions 0.10.0 through 0.10.x. The flaw arises because engine-level JavaScript stack overflow errors escape KaTeX standard error handling. Svelte's fallback rendering path assigns the raw, unescaped mathematical input string directly to the DOM using the unsafe {@html} directive, enabling arbitrary client-side code execution. This allows attackers to steal session tokens and perform unauthorized administrative actions when users view malicious messages. The vulnerability has been fully resolved in version 0.11.0.
CVE-2026-70493 is a critical Regular Expression Denial of Service (ReDoS) vulnerability affecting Open WebUI from version 0.9.6 up to (but excluding) 0.11.0. An authenticated user can submit a custom, highly complex regular expression pattern to search files within the knowledge base. Because these expressions are compiled and executed synchronously using Python's standard backtracking re module inside an asynchronous event loop, the server becomes unresponsive. A single request is capable of stalling the entire platform, denying access to all concurrent users of the system.
CVE-2026-70588 is a stored Cross-Site Scripting (XSS) vulnerability in Ghost CMS versions 5.26.0 through 6.54.0. The vulnerability exists within the Universal Import feature of the Ghost Admin interface. When processing imported content from third-party platforms such as Revue, the importer fails to sanitize user-controlled HTML tags, rich-text structured JSON, or link fields before rendering them in the Ghost Admin panel and front-end template rendering contexts.
CVE-2026-53948 is a stored cross-site scripting (XSS) vulnerability in the Ghost content management system. Affected versions (v6.19.4 up to v6.21.0) trusted the client-supplied Content-Type header during file uploads via the Admin API. This allowed authenticated attackers to upload benignly-named files with executable MIME types (like text/html), executing scripts in visitor browsers when hosted on integrated cloud platforms like S3 or GCS.
A business logic vulnerability in Ghost CMS allows unauthenticated remote users to redeem deactivated or archived promotional subscription offers by programmatically passing old offer identifiers during the checkout session initialization.