-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
[Bug]: QQBot credential backups bypass gateway state isolation #84313
Copy link
Copy link
Closed
Labels
P0Emergency: data loss, security bypass, crash loop, or unusable core runtime.Emergency: data loss, security bypass, crash loop, or unusable core runtime.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.Auth, provider routing, model choice, or SecretRef resolution may break.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Description
Metadata
Metadata
Assignees
Labels
P0Emergency: data loss, security bypass, crash loop, or unusable core runtime.Emergency: data loss, security bypass, crash loop, or unusable core runtime.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.Auth, provider routing, model choice, or SecretRef resolution may break.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Priority
None yet
Severity Assessment
CVSS Assessment
Threat Model Alignment
Classification:
security-specificopenclaw/SECURITY.mdsays "For advanced setups, multiple gateways on one machine are possible, but only with strict isolation" and "For untrusted-user isolation, split by trust boundary: separate gateways and separate OS users/hosts per boundary." This finding breaks the documented separate-gateway isolation layer because QQBot persists credentials in a home-global path instead of the activeOPENCLAW_STATE_DIR. It is not the out-of-scope shared-gateway case because the repro uses two different gateway instances with different configs and state directories, matchingdocs/gateway/index.md:157-185anddocs/gateway/multiple-gateways.md:119-127.Impact
A QQBot account that reaches READY on Gateway A writes a reusable credential backup into
~/.openclaw/qqbot/data/. Gateway B, started under the same OS account but a differentOPENCLAW_STATE_DIR, can silently import that backup and overwrite its own config with Gateway A'sappIdandclientSecret, collapsing two supposedly isolated gateway profiles into one shared QQBot identity.Affected Component
File:
extensions/qqbot/src/engine/utils/platform.ts:42-45,extensions/qqbot/src/engine/utils/data-paths.ts:31-37,extensions/qqbot/src/channel.ts:168-170,282-295Technical Reproduction
$HOMEbut with differentOPENCLAW_CONFIG_PATHandOPENCLAW_STATE_DIRvalues, following the multi-gateway isolation guidance indocs/gateway/index.md:157-185.default(or any shared account id), let the channel reach READY, and observepersistAccountCredentialSnapshot()callsaveCredentialBackup().getCredentialBackupFile()resolves throughgetQQBotDataPath(), Gateway A writescredential-backup-default.jsonunder~/.openclaw/qqbot/data/instead of under Gateway A's state directory.appIdorclientSecret. DuringqqbotPlugin.gateway.startAccount(),loadCredentialBackup(account.accountId)reads Gateway A's shared backup andwriteOpenClawConfigThroughRuntime()injects those credentials into Gateway B's config.Demonstrated Impact
The exploit path is deterministic and does not require modifying trusted local files ahead of time: ordinary QQBot startup on Gateway A creates the credential backup, and ordinary QQBot startup on Gateway B consumes it. The root cause is architectural coupling to
os.homedir()/~/.openclaw/qqbotrather than the active gateway state resolver. Existing controls do not prevent the cross-profile import because the restore path runs before the channel starts, explicitly rewrites Gateway B's config with the recovered secret, and keys the backup only byaccountId. That lets one isolated gateway profile inherit another profile's bot identity and message authority, violating the documented per-instance config/state split.Environment
Inspected in
openclaw/atupstream/maincommit3d96111a5afe377b529c9bb5a9db510d74607344. The vulnerable storage and restore paths are implemented inextensions/qqbot/src/engine/utils/platform.ts,extensions/qqbot/src/engine/utils/data-paths.ts, andextensions/qqbot/src/channel.ts. The expected isolation model is documented indocs/gateway/index.md:157-185,docs/gateway/multiple-gateways.md:119-127, andopenclaw/SECURITY.md:136-139,236.Remediation Advice
Route all QQBot durable state, especially credential backups, through the active OpenClaw state-directory resolver and include the gateway profile/state directory in the backup scope so one gateway instance cannot restore another instance's QQBot credentials.