Back to skill

Security audit

Last30Days Community Intelligence for OpenClaw

Security checks for vulnerabilities and agentic risk

Overview

This is a useful research skill, but it can automatically reuse existing Codex and X browser session credentials without clear opt-in in the primary docs.

Before installing, decide whether you are comfortable with the skill using your existing Codex/OpenAI login and X browser session for automated research. Prefer dedicated, revocable API keys and a separate browser profile where possible, review scheduled watchlists carefully because they send topics to external providers on a timer, and avoid running X/Codex-backed modes on sensitive topics unless you accept those account and privacy implications.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/lib/env.py:35
Finding
Automatic Reuse of Ambient Codex and Browser Session Credentials<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/env.py:35-37, 89-151`; `scripts/lib/vendor/bird-search/lib/cookies.js:72-89, 121-159` **Vulnerability Type**: Automatic access to ambient account credentials beyond dedicated Skill secrets **Risk Level**: Medium ### Vulnerable Code ```python CODEX_AUTH_FILE = Path(os.environ.get("CODEX_AUTH_FILE", str(Path.home() / ".codex" / "auth.json"))) ``` ```python def load_codex_auth(path: Path = CODEX_AUTH_FILE) -> Dict[str, Any]: """Load Codex auth JSON.""" if not path.exists(): return {} try: with open(path, "r") as f: return json.load(f) except Exception: return {} def get_codex_access_token() -> tuple[Optional[str], str]: """Get Codex access token from auth.json. Returns: (token, status) where status is 'ok', 'missing', or 'expired' """ auth = load_codex_auth() token = None if isinstance(auth, dict): tokens = auth.get("tokens") or {} if isinstance(tokens, dict): token = tokens.get("access_token") if not token: token = auth.get("access_token") if not token: return None, AUTH_STATUS_MISSING if _token_expired(token): return None, AUTH_STATUS_EXPIRED return token, AUTH_STATUS_OK def get_openai_auth(file_env: Dict[str, str]) -> OpenAIAuth: """Resolve OpenAI auth from API key or Codex login.""" api_key = os.environ.get('OPENAI_API_KEY') or file_env.get('OPENAI_API_KEY') if api_key: return OpenAIAuth( token=api_key, source=AUTH_SOURCE_API_KEY, status=AUTH_STATUS_OK, account_id=None, codex_auth_file=str(CODEX_AUTH_FILE), ) codex_token, codex_status = get_codex_access_token() if codex_token: account_id = extract_chatgpt_account_id(codex_token) if account_id: return OpenAIAuth( token=codex_token, ...[truncated 4652 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require explicit opt-in before reading `~/.codex/auth.json` or any browser credential store. 2. Default to dedicated, revocable API keys stored in the Skill's mode-`0600` secrets file. 3. Add flags such as `LAST30DAYS_ALLOW_CODEX_AUTH=1` and `LAST30DAYS_ALLOW_BROWSER_COOKIES=1`, with both disabled by default. 4. Clearly document all credential paths, fallback behavior, recipient domains, and authorization implications in the primary `SKILL.md`. 5. Allow the user to select a specific browser and profile rather than probing Safari, Chrome, and Firefox automatically. 6. Isolate browser-cookie access in a minimal helper with narrowly restricted filesystem and network permissions. 7. Avoid exposing raw credentials to child processes where possible; pass them through a protected IPC mechanism or a dedicated credential broker. 8. Provide a diagnostic mode that reports credential availability without reading or returning credential values. 9. Pin and verify the integrity of the browser-cookie dependency and review updates before deployment. ]]>

T02 · Agent Memory Poisoning

Note
Location
variants/open/SKILL.md:46
Finding
Persistent Free-Form Agent Context Can Retain Untrusted Instructions<![CDATA[ ## Vulnerability Details **File Location**: `variants/open/SKILL.md:46`; `variants/open/context.md:1-16` **Vulnerability Type**: Unvalidated persistent agent memory **Risk Level**: Low ### Vulnerable Code ```markdown ## Load Context At session start, read `${SKILL_ROOT}/variants/open/context.md` for user preferences and source quality notes. Update it after interactions. ``` ```markdown # last30days Context Agent memory for improving research quality over time. ## User Preferences <!-- Record preferences discovered during interactions --> <!-- e.g., "Prefers detailed technical analysis over general summaries" --> ## Source Quality Notes <!-- Record which sources work best for which topics --> <!-- e.g., "r/LocalLLaMA is highest signal for AI hardware topics" --> <!-- e.g., "@kaboratech provides reliable AI tool reviews" --> ## Interaction History <!-- Record topics researched and useful follow-up patterns --> <!-- e.g., "2026-02-14: Researched 'AI video tools', user wanted Runway vs Kling comparison" --> ``` ### Technical Analysis The open variant instructs the Agent to update a free-form Markdown context file after interactions and load that file at the start of later sessions. The design does not define a structured schema, distinguish trusted user preferences from remote research content, sanitize instruction-like text, require confirmation before persistence, or establish a retention policy. Because research results originate from external websites and social platforms, attacker-controlled text may enter the Agent's working context. If such content is summarized or copied into `context.md`, it becomes persistent input to future sessions. Free-form Markdown makes stored data difficult to distinguish from operational instructions, creating a memory-poisoning risk. ### Attack Path 1. An attacker publishes content designed to appear in search results for a monitored topic. 2. The Skill retrieves the content during research. 3. The content ...[truncated 1066 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace free-form Markdown memory with a structured format containing an explicit field allowlist. 2. Separate inert research data from Agent instructions and ensure stored values are always treated as untrusted data. 3. Never persist remote text verbatim; normalize and validate source identifiers, dates, preference values, and topic names. 4. Require explicit user approval before adding or changing persistent preferences and source-quality rules. 5. Record provenance for every entry, including whether it originated from the user, the Agent, or a remote source. 6. Apply length limits and reject imperative or instruction-like content in fields intended only for data. 7. Add expiration, inspection, correction, and deletion mechanisms. 8. Do not automatically load interaction history unless the user enables persistent memory. 9. Keep operational Skill instructions in a read-only file separate from writable memory. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (107)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documentation instructs users to rely on browser cookies or set AUTH_TOKEN and CT0 for X access, but the high-risk credential handling is not prominently framed as sensitive or dangerous. Encouraging a skill to read browser-derived auth material and construct authenticated session headers expands access beyond ordinary public search and can expose private account context or leak long-lived tokens if logs, files, or downstream tools mishandle them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documentation instructs users to rely on browser cookies or set AUTH_TOKEN and CT0 for X access, but the high-risk credential handling is not prominently framed as sensitive or dangerous. Encouraging a skill to read browser-derived auth material and construct authenticated session headers expands access beyond ordinary public search and can expose private account context or leak long-lived tokens if logs, files, or downstream tools mishandle them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The documentation instructs users to rely on browser cookies or set AUTH_TOKEN and CT0 for X access, but the high-risk credential handling is not prominently framed as sensitive or dangerous. Encouraging a skill to read browser-derived auth material and construct authenticated session headers expands access beyond ordinary public search and can expose private account context or leak long-lived tokens if logs, files, or downstream tools mishandle them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documentation instructs users to rely on browser cookies or set AUTH_TOKEN and CT0 for X access, but the high-risk credential handling is not prominently framed as sensitive or dangerous. Encouraging a skill to read browser-derived auth material and construct authenticated session headers expands access beyond ordinary public search and can expose private account context or leak long-lived tokens if logs, files, or downstream tools mishandle them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The documentation instructs users to rely on browser cookies or set AUTH_TOKEN and CT0 for X access, but the high-risk credential handling is not prominently framed as sensitive or dangerous. Encouraging a skill to read browser-derived auth material and construct authenticated session headers expands access beyond ordinary public search and can expose private account context or leak long-lived tokens if logs, files, or downstream tools mishandle them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The documentation instructs users to rely on browser cookies or set AUTH_TOKEN and CT0 for X access, but the high-risk credential handling is not prominently framed as sensitive or dangerous. Encouraging a skill to read browser-derived auth material and construct authenticated session headers expands access beyond ordinary public search and can expose private account context or leak long-lived tokens if logs, files, or downstream tools mishandle them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The documentation instructs users to rely on browser cookies or set AUTH_TOKEN and CT0 for X access, but the high-risk credential handling is not prominently framed as sensitive or dangerous. Encouraging a skill to read browser-derived auth material and construct authenticated session headers expands access beyond ordinary public search and can expose private account context or leak long-lived tokens if logs, files, or downstream tools mishandle them.

Ae1

High
Category
analysis-evasion
Content
- OpenClaw skill packaging (`skill.json`, this `SKILL.md`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/watchlist.py add "TOPIC"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/watchlist.py add "TOPIC"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/watchlist.py add "TOPIC"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/watchlist.py add "TOPIC"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Credential Access

High
Category
Privilege Escalation
Content
**Safari (recommended on Mac):** Just be logged into x.com. No setup needed.

**Chrome:** Works, but macOS will prompt you to allow Keychain access the first time. Click "Allow" (or "Always Allow" to stop future prompts).

**Firefox:** Just be logged into x.com. No setup needed.
Confidence
90% confidence
Finding
The README normalizes granting browser/Keychain access so the vendored X client can read session material from the local browser context. Even though framed as convenience, this expands the credential exposure surface to a third-party tool path and can enable misuse of X session secrets if the tool or its dependencies are compromised.

Credential Access

High
Category
Privilege Escalation
Content
"deep": 60,
}

# Module-level credentials injected from .env config
_credentials: Dict[str, str] = {}
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"deep": 60,
}

# Module-level credentials injected from .env config
_credentials: Dict[str, str] = {}
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"deep": 60,
}

# Module-level credentials injected from .env config
_credentials: Dict[str, str] = {}
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"deep": 60,
}

# Module-level credentials injected from .env config
_credentials: Dict[str, str] = {}
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"deep": 60,
}

# Module-level credentials injected from .env config
_credentials: Dict[str, str] = {}
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"deep": 60,
}

# Module-level credentials injected from .env config
_credentials: Dict[str, str] = {}
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"deep": 60,
}

# Module-level credentials injected from .env config
_credentials: Dict[str, str] = {}
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"deep": 60,
}

# Module-level credentials injected from .env config
_credentials: Dict[str, str] = {}
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"deep": 60,
}

# Module-level credentials injected from .env config
_credentials: Dict[str, str] = {}
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def set_credentials(auth_token: Optional[str], ct0: Optional[str]):
    """Inject AUTH_TOKEN/CT0 from .env config so Node subprocesses can use them."""
    if auth_token:
        _credentials['AUTH_TOKEN'] = auth_token
    if ct0:
Confidence
86% confidence
Finding
This function accepts X auth cookies/tokens from `.env` and stores them for subprocess use, enabling the skill to perform authenticated requests to a third-party service. In the context of an agent skill, using operator credentials for automated external searches increases privacy and account-risk exposure, especially if users are not clearly informed and if the downstream helper is not tightly controlled.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
def _subprocess_env() -> Dict[str, str]:
    """Build env dict for Node subprocesses, merging injected credentials."""
    env = os.environ.copy()
    env.update(_credentials)
    return env
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Credential Access

High
Category
Privilege Escalation
Content
# Preferred secrets file lives inside workspace so skills remain self-contained:
#   ~/.openclaw/workspace/.secrets/last30days.env
# Legacy fallback is still supported:
#   ~/.config/last30days/.env
OPENCLAW_WORKSPACE = Path(
    os.environ.get("OPENCLAW_WORKSPACE", str(Path.home() / ".openclaw" / "workspace"))
)
Confidence
78% confidence
Finding
The code is explicitly designed to locate and read credential-bearing `.env` files, including from a workspace secrets directory. Secret loading is expected for functionality, but from a security-review perspective it is still credential access and increases blast radius if the skill or dependencies misuse the resulting config.

Static analysis

Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/lib/vendor/bird-search/lib/twitter-client-base.js:38

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/lib/vendor/bird-search/bird-search.mjs:96

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/lib/vendor/bird-search/lib/cookies.js:134

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/lib/vendor/bird-search/lib/twitter-client-base.js:19