T05 · Unauthorized Access and Privilege Escalation
- Location
SKILL.md:50- Finding
Undeclared Password-Manager Credential Access
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 8–12, 23–26, and 50–51
Vulnerability Type: Undeclared credential retrieval that exceeds the documented environment-variable requirement
Risk Level: MediumVulnerable Code
yaml primaryEnv: ZOTERO_API_KEY requires: env: - ZOTERO_API_KEYmarkdown ## Credentials - **API Key:** `op read "op://OpenClaw/Zotero API Credentials/credential"` - **User ID:** `10425097` - **Base URL:** `https://api.zotero.org/users/10425097`python def get_zotero_key(): return subprocess.check_output(['op', 'read', 'op://OpenClaw/Zotero API Credentials/credential']).decode().strip()Technical Analysis
The skill metadata declares
ZOTERO_API_KEYas its required credential, creating the expectation that the skill will use only a caller-supplied environment variable. The implementation instead invokes the local 1Password CLI and retrieves a credential from a fixed vault path.This behavior expands the access boundary from a single explicitly supplied environment variable to the user's password-manager integration. It also binds the skill to a hard-coded Zotero account and credential record. If the local
opsession is authorized, the skill can obtain a write-capable key without using the credential the operator intentionally provided.The credential is passed only to the official Zotero API in the documented code, and no evidence of credential exfiltration to an unrelated endpoint was found. Nevertheless, accessing an undeclared password-manager record violates least-privilege and transparent capability declaration principles.
Attack Path
- A user installs or invokes the skill based on metadata stating that only
ZOTERO_API_KEYis required. - The agent follows the provided implementation and calls
get_zotero_key(). subprocess.check_output()invokes the localopexecutable.- The command requests `op:// ...[truncated 848 chars]
- A user installs or invokes the skill based on metadata stating that only
- Remediation
View remediation
Remediation Suggestions
-
Retrieve the declared environment variable directly:
python import os def get_zotero_key(): return os.environ["ZOTERO_API_KEY"] -
Remove the fixed 1Password vault reference from the skill.
-
If optional 1Password integration is necessary:
- Declare the
opCLI and password-manager access explicitly in metadata. - Require affirmative user consent before invoking it.
- Make the vault path configurable rather than account-specific.
- Prefer an environment variable populated externally through 1Password secret references.
- Declare the
-
Avoid hard-coding the Zotero user ID. Require an explicit
ZOTERO_USER_IDconfiguration value and validate it before performing writes. -
Use a narrowly scoped Zotero API key granting only the permissions required for ingestion.
-
