Feb 17, 2026·5 min read·7 visits
OpenClaw's Google Chat extension confused immutable IDs with mutable email addresses. If you allowed 'users/email@example.com', the system stripped the prefix and matched against the email field. If that email gets reassigned to a new account (different ID), the new user inherits access. Fixed in 2026.2.14 by strictly enforcing ID checks for prefixed entries.
A critical authorization bypass vulnerability in OpenClaw allows attackers to spoof authorized users via Google Chat. By exploiting a logic flaw in how the system handles 'users/' prefixes in allowlists, a new Google account recycling an old email address can inherit the privileges of the previous owner, granting full control over the AI assistant.
We all love personal AI assistants. They read our emails, summarize our chats, and occasionally execute code on our behalf. OpenClaw is one of the cool kids on the block, letting you control your digital life via Google Chat. But here is the thing about 'identity' in the cloud: it is messy. There are things that never change (Immutable IDs) and things that change all the time (Email Addresses).
When you build a security gate for an AI that can potentially run shell commands or read sensitive logs, you better be damn sure you know who is knocking. OpenClaw tried to be flexible, allowing admins to define authorized users in a variety of formats. Unfortunately, in their quest for flexibility, they created a classic 'fuzzy matching' vulnerability. They effectively built a biometric lock that also accepts a photocopy of a face if you hold it up just right.
The root cause lies in extensions/googlechat/src/monitor.ts. The developers wanted to support allowlist entries that looked like Google resource names (e.g., users/10384...) but also wanted to support human-readable emails. The fatal mistake was treating the prefix users/ as a decoration rather than a strict type designator.
When an incoming message arrived, the system took the allowlist entries and stripped the users/ prefix. It then checked if the remaining string matched either the sender's immutable ID or the sender's email address. This creates a dangerous ambiguity. If an admin wrote users/alice@corp.com in the config, they likely intended to lock it to a specific user. But the code interpreted this as: 'Does the sender have the email alice@corp.com?'.
This distinction is critical because emails are mutable principals. If Alice leaves the company and her account is deleted, the immutable ID dies with it. But if Bob joins a month later and IT recycles the alias alice@corp.com (perhaps for a department role), Bob now matches the allowlist, despite having a completely different Google account ID.
Let's look at the vulnerable logic in isSenderAllowed. It is a masterclass in 'trying too hard to be helpful'.
// THE VULNERABLE LOGIC (Simplified)
const withoutPrefix = entry.replace(/^users\//i, "");
// 1. Check if it matches the immutable ID
if (withoutPrefix === senderId) return true;
// 2. Check if it matches the mutable Email
if (withoutPrefix === senderEmail) return true;See the issue? The code assumes that stripping users/ leaves you with a generic identifier that could be valid for either field.
The fix, introduced in commit c8424bf, forces strict typing. If you use the users/ prefix, the system now only checks against the ID. If you want to check an email, you must provide the raw email without a prefix.
// THE FIX
if (withoutPrefix.startsWith("users/")) {
// STRICT CHECK: Only match ID
return normalizeUserId(withoutPrefix) === normalizedSenderId;
}
// Fallback for raw emails (no prefix)
if (isEmailLike(withoutPrefix)) {
return withoutPrefix === normalizedEmail;
}This change eliminates the ambiguity. users/alice@corp.com will now fail because the logic expects an ID after the prefix, and an email string does not equal a numeric ID.
How do we weaponize this? We need a scenario where we can inherit a mutable identifier (email) that is trusted in the config, but attached to a new account (different ID).
"allowedUsers": ["users/admin@target.com"].admin@target.com account is deleted (employee leaves) or the alias is removed.admin@target.com. This could be through standard IT provisioning (getting hired and requesting the alias) or an IdP misconfiguration that allows alias claiming.!exec cat /etc/passwd.Under the old logic, OpenClaw looks at your message. It sees your email is admin@target.com. It looks at the config users/admin@target.com. It strips the prefix. It compares strings. It opens the door. You are now the admin.
This is not just about reading chat logs. OpenClaw is designed to be an agent. It has tools. It has context. Gaining unauthorized access to a personal AI assistant is effectively gaining access to the user's digital brain.
The severity depends heavily on what tools you have given your AI. If it's just a chatbot, it's a privacy breach. If it's an agent with kubectl access, it's game over.
The remediation is straightforward: Stop guessing types.
2026.2.14 immediately.config.json or environment variables.
users/jane@doe.comusers/10492838492 (Get the actual Google User ID)jane@doe.com (If you accept the risk of email recycling)Security controls based on mutable identifiers are always risky. Whenever possible, bind permissions to the immutable GUID/UUID of the identity, not the human-readable label pasted on top of it.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
OpenClaw OpenClaw | < 2026.2.14 | 2026.2.14 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-290 (Spoofing) |
| Attack Vector | Network |
| CVSS Score | 6.8 (Estimated) |
| Confidentiality | High |
| Integrity | High |
| Patch Status | Released (2026.2.14) |
Authentication Bypass by Spoofing