Back to skill

Security audit

feynman-lobster

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent learning purpose, but its panel can expose stored project/profile data through an unauthenticated local API and unsafe dashboard rendering.

Review before installing. Only use this skill with paths you are comfortable having read and summarized into persistent local files. Avoid running the web panel until the API requires a per-launch token, CORS is restricted, and the dashboard escapes stored data. Use an isolated OpenClaw workspace for sensitive projects and confirm how to delete contracts, profile notes, memory files, and supervision links.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/feynman_api.py:539
Finding
Unauthenticated Wildcard-CORS API Exposes Private Workspace Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/feynman_api.py`, lines 539-606 **Vulnerability Type**: Unauthenticated local API and overly permissive CORS **Risk Level**: High ### Vulnerable Code ```python def _send_json(self, payload: dict, code: int = 200) -> None: data = json.dumps(payload, ensure_ascii=False).encode("utf-8") self.send_response(code) self.send_header("Content-Type", "application/json; charset=utf-8") self.send_header("Content-Length", str(len(data))) self.send_header("Cache-Control", "no-store") self.send_header("Access-Control-Allow-Origin", "*") self.send_header("Access-Control-Allow-Methods", "GET,OPTIONS") self.send_header("Access-Control-Allow-Headers", "Content-Type,Authorization") self.end_headers() self.wfile.write(data) def do_OPTIONS(self) -> None: self.send_response(204) self.send_header("Access-Control-Allow-Origin", "*") self.send_header("Access-Control-Allow-Methods", "GET,OPTIONS") self.send_header("Access-Control-Allow-Headers", "Content-Type,Authorization") self.end_headers() ``` The following unauthenticated routes return workspace data: ```python if path == "/api/feynman/contracts": contracts = self.store.contracts() self._send_json({"contracts": contracts, "total": len(contracts)}) return if path == "/api/feynman/profile": self._send_json({"profile": {"markdown": self.store.user_profile()}}) return if len(parts) == 2 and parts[1] == "conversations": q = parse_qs(parsed.query) try: limit = int((q.get("limit") or ["5"])[0]) except ValueError: limit = 5 clause_id = (q.get("clause_id") or [""])[0].strip() or None limit = max(1, min(limit, 50)) convs = self.store.conversations(parts[0], limit, clause_id=clause_id) self._send_json({"conversations": convs, "total": len(convs)}) return if len(parts) == 2 and parts[1] == "memory": memory_text = self.store.contract_memory(parts[0 ...[truncated 2160 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate a cryptographically random API token for each launch and require it on every API request. 2. Reject requests without a valid `Authorization: Bearer ...` header. 3. Replace wildcard CORS with an exact allowlist containing only the intended panel origin, such as `http://127.0.0.1:19380`. 4. Validate both the `Origin` and `Host` headers. Reject unexpected origins instead of reflecting them. 5. Avoid exposing the token in URLs because URLs can leak through logs and browser history. 6. Return only the minimum fields required by the selected dashboard view. 7. Consider separating profile and conversation access behind an explicit user opt-in. 8. Add automated tests proving that unauthenticated and foreign-origin requests are rejected. 9. Keep loopback binding as defense in depth, but do not treat it as a replacement for authorization. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
web/index.html:111
Finding
Stored DOM-Based Cross-Site Scripting in the Web Dashboard<![CDATA[ ## Vulnerability Details **File Location**: `web/index.html`, lines 111-181 **Vulnerability Type**: Stored DOM XSS through unsafe `innerHTML` interpolation **Risk Level**: High ### Vulnerable Code The dashboard creates a large HTML template from contract-controlled values and assigns it to `innerHTML`: ```javascript app.innerHTML=` <div class="main"> <div class="left"> <span class="label">契约 ${pad(idx+1)} / ${pad(contracts.length)} ${demoTag}</span> <p class="hero">${hero}</p> <h1 class="goal">${c.goal.toUpperCase()}</h1> <div class="bar"><span>${m} / ${t}</span><div class="bar-track"><div class="bar-fill" style="width:${t?m/t*100:0}%"></div></div></div> <div class="specs"> <span class="spec-k">DEADLINE</span><span>${fmtDate(c.deadline)}${c.status==='active'?'(还剩 '+daysLeft(c.deadline)+' 天)':''}</span> <span class="spec-k">GOAL</span><span>${c.motivation||'-'}</span> <span class="spec-k">REWARD</span><span>${c.reward||'-'}</span> </div> ``` Additional unescaped fields are used in the details overlay: ```javascript <p><strong>${c.goal}</strong> ${demoTag} · 契约 ${pad(idx+1)} / ${pad(contracts.length)}</p> <p class="specs" style="margin-top:.5rem"><span class="spec-k">DEADLINE</span><span>${fmtDate(c.deadline)}</span><span class="spec-k">GOAL</span><span>${c.motivation||'-'}</span><span class="spec-k">REWARD</span><span>${c.reward||'-'}</span></p> ${(c.supervisors||[]).length?`<p><span class="spec-k">SUPERVISOR</span> ${c.supervisors.map(s=>s.agent_name).join(' · ')}</p>`:''} <h2>进度</h2> ${(c.clauses||[]).map(cl=>`<div class="clause ${cl.status}">${cl.status==='mastered'?'☑':cl.status==='in_progress'?'◐':'☐'} ${cl.concept}${cl.added_reason?' <span class="meta">新增:'+cl.added_reason+'</span>':''}${cl.mastered_at?' <span class="meta">'+fmtDate(cl.mastered_at)+' mastered</span>':cl.status==='in_progress'&&cl.attempts?' <span class="meta">尝试 '+cl.attempts+' 次</span>':''}</div>`).join('')} <h2>学习资料</h2> ${(c.reso ...[truncated 2377 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Stop constructing the interface through `innerHTML` with untrusted values. 2. Create elements using DOM APIs and assign all textual fields through `textContent`. 3. If HTML templating remains necessary, apply context-aware escaping to every untrusted value, including attribute values. 4. Validate resource URLs with the `URL` API and allow only explicit schemes such as `https:` and, if required, `http:`. 5. Reject `javascript:`, `data:`, `file:`, and other unintended URL schemes. 6. Add `rel="noopener noreferrer"` to links using `target="_blank"`. 7. Validate contract records against a strict schema before rendering them. 8. Add a restrictive Content Security Policy that disallows inline scripts and event handlers. 9. Add regression tests using malicious values in every contract-controlled field. ]]>

T08 · Insecure Dependencies

Warning
Location
web/package.json:4
Finding
Unpinned On-Demand Package Execution Through npx<![CDATA[ ## Vulnerability Details **File Location**: `web/package.json`, lines 4-6 **Vulnerability Type**: Mutable third-party dependency execution **Risk Level**: Medium ### Vulnerable Code ```json "scripts": { "dev": "npx serve -p 19380", "start": "npx serve -p 19380" } ``` ### Technical Analysis The project does not declare `serve` as a pinned local dependency and does not include a lockfile. When `npm start` or `npm run dev` invokes `npx serve`, `npx` may resolve, download, and execute the current registry version of the package. The code executed at runtime can therefore differ from what was available during this audit. This violates reproducible-build and reviewed-dependency principles. Package lifecycle scripts and the downloaded executable run with the current user's operating-system privileges. No evidence was found that the current `serve` package is malicious. The vulnerability is the unsafe, mutable dependency resolution mechanism. ### Attack Path 1. The user runs `npm start` or `npm run dev` in the `web` directory. 2. `npx` looks for a local `serve` binary. 3. Because no pinned local dependency is defined, `npx` may retrieve the package from the configured npm registry. 4. A compromised registry release, account takeover, or unexpected future package version is downloaded. 5. Package installation or runtime code executes with the user's privileges. ### Impact Assessment A compromised resolved package could execute arbitrary commands with the invoking user's privileges. Depending on that user's access, this could expose workspace files, credentials available to the process, source code, and network-accessible resources. The finding does not establish that such compromise has occurred; it identifies an avoidable supply-chain execution path. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add an exact reviewed version of `serve` to `devDependencies`. 2. Commit a package lockfile containing resolved versions and integrity hashes. 3. Invoke the local binary through the package script rather than relying on on-demand `npx` installation. 4. Use `npm ci` in controlled environments to enforce lockfile resolution. 5. Configure registry allowlists and dependency auditing where possible. 6. Prefer the existing Python standard-library HTTP server if no Node-specific functionality is needed, eliminating this dependency entirely. ]]>

T08 · Insecure Dependencies

Note
Location
scripts/requirements.txt:1
Finding
Unbounded and Apparently Unused Python Dependency<![CDATA[ ## Vulnerability Details **File Location**: `scripts/requirements.txt`, lines 1-3 **Vulnerability Type**: Non-reproducible dependency resolution **Risk Level**: Low ### Vulnerable Code ```text # SecondMe A2A Client 依赖 # pip install -r requirements.txt requests>=2.28.0 ``` ### Technical Analysis The lower-bound-only requirement permits pip to install any future compatible release of `requests` and its transitive dependencies. Installation results can therefore change after audit without changes to the Skill package. The reviewed `scripts/feynman_api.py` implementation does not import `requests`, making this dependency appear unnecessary for the current shipped functionality. Unused dependencies increase supply-chain exposure without providing a corresponding functional benefit. No evidence was found that the current `requests` package is malicious. ### Attack Path 1. A user follows the installation comment and runs `pip install -r scripts/requirements.txt`. 2. Pip resolves the latest package versions satisfying the lower bound. 3. The resolved package set may differ from the versions reviewed by the publisher. 4. Installation-time code from a compromised or unexpectedly changed dependency executes in the user's Python environment. ### Impact Assessment A compromised dependency installation could execute with the privileges of the user running pip and affect the associated Python environment. The practical current risk is limited because the dependency is not automatically installed by the supplied setup script and is not used by the audited API. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `requests` if it is not required by shipped functionality. 2. If it is required for a future A2A client, pin an exact reviewed version. 3. Pin transitive dependencies through a generated lockfile. 4. Use package hashes with pip's hash-checking mode. 5. Separate optional A2A dependencies from the core local dashboard requirements. 6. Regularly review and update pinned versions through a controlled dependency-update process. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/feynman_api.py:137
Finding
Read-Only API Performs Silent Non-Atomic Contract Deletion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/feynman_api.py`, lines 137-153 **Vulnerability Type**: Unexpected data mutation and unsafe file replacement **Risk Level**: Low ### Vulnerable Code The module describes itself as read-only: ```python """Feynman Lobster local read-only API bridge. Serves real data from OpenClaw workspace files so the web panel can render contracts and memory even when Gateway plugin endpoints are unavailable. """ ``` However, a read operation can rewrite the contract file: ```python def _cleanup_demo_contracts_in_file_if_needed(self, raw_data: object, contracts: list[dict], list_mode: bool) -> None: has_demo = any(self._is_demo_contract(c) for c in contracts) has_real = any(not self._is_demo_contract(c) for c in contracts) if not (has_demo and has_real): return cleaned = [c for c in contracts if not self._is_demo_contract(c)] try: if list_mode and isinstance(raw_data, list): self.contracts_file.write_text(json.dumps(cleaned, ensure_ascii=False, indent=2), encoding="utf-8") elif isinstance(raw_data, dict): payload = dict(raw_data) payload["contracts"] = cleaned self.contracts_file.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8") except Exception: # Keep serving data even if cleanup write fails. pass ``` Demo classification is based partly on an identifier prefix: ```python @staticmethod def _is_demo_contract(contract: dict) -> bool: if not isinstance(contract, dict): return False cid = str(contract.get("id") or "") return bool(contract.get("__demo")) or cid.startswith("demo_") ``` ### Technical Analysis Loading contracts calls cleanup logic that removes entries marked `__demo` or whose IDs begin with `demo_` whenever another contract is considered real. The modified list is written directly to `contracts.json`. This creates several integrity proble ...[truncated 1521 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make all GET and display-oriented operations side-effect free. 2. Move demo cleanup into an explicit, separately invoked migration command. 3. Identify built-in demo records using exact immutable identifiers rather than a broad `demo_` prefix. 4. Require clear provenance metadata before deleting any record. 5. Create a backup before migration and report every removed record to the user. 6. Write updates to a temporary file in the same directory, flush and synchronize it, then atomically replace the destination. 7. Use file locking or optimistic concurrency checks to avoid overwriting concurrent changes. 8. Do not suppress all exceptions; log actionable failures without exposing sensitive file contents. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (49)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Starting static servers, API bridge processes, probing ports, opening browsers, and writing temp logs are privileged operational behaviors inconsistent with a simple coaching assistant. These actions enlarge the attack surface, may reveal local data through exposed endpoints, and can interfere with the user's environment without informed consent.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Starting static servers, API bridge processes, probing ports, opening browsers, and writing temp logs are privileged operational behaviors inconsistent with a simple coaching assistant. These actions enlarge the attack surface, may reveal local data through exposed endpoints, and can interfere with the user's environment without informed consent.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Starting static servers, API bridge processes, probing ports, opening browsers, and writing temp logs are privileged operational behaviors inconsistent with a simple coaching assistant. These actions enlarge the attack surface, may reveal local data through exposed endpoints, and can interfere with the user's environment without informed consent.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Starting static servers, API bridge processes, probing ports, opening browsers, and writing temp logs are privileged operational behaviors inconsistent with a simple coaching assistant. These actions enlarge the attack surface, may reveal local data through exposed endpoints, and can interfere with the user's environment without informed consent.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Starting static servers, API bridge processes, probing ports, opening browsers, and writing temp logs are privileged operational behaviors inconsistent with a simple coaching assistant. These actions enlarge the attack surface, may reveal local data through exposed endpoints, and can interfere with the user's environment without informed consent.

Intent-Code Divergence

High
Confidence
97% confidence
Finding
The top-level documentation explicitly claims the bridge is read-only, yet the implementation writes to disk via cleanup logic. This mismatch can mislead users and reviewers into granting the process broader trust than warranted, increasing the chance of unnoticed data modification in a sensitive workspace.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The module is presented as a read-only API bridge, but the read path can rewrite contracts.json to remove demo entries when both demo and real contracts are present. Unexpected mutation during a GET-driven code path breaks the documented trust boundary and can silently alter user workspace data, creating integrity and auditability risks.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
fi

# ClawHub 只接受文本文件,移除 .gitignore(避免被误判为非文本)
rm -f "$TEMP_DIR/.gitignore"

echo "✓ 已导出到 $TEMP_DIR"
echo ""
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The skill instructions and all user-facing example messages are written exclusively in Chinese, including the reminder and re-engagement text that would be pushed to the user. There is no indication that the user can choose a language or that the skill is intentionally limited to a Chinese-language context, which creates a locale-policy concern.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
This markdown file presents all user-facing documentation in Chinese and does not indicate that the language is optional, configurable, or justified by a region-specific requirement. That can violate a language/locale policy when users are not given an explicit opt-in or alternative language.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The README documents broad conversational triggers like '我在做', '我想学', and 'feynman', which can overlap with ordinary user speech and cause unintended activation. In a chat-integrated skill that reads project paths, notes, and profile data, accidental routing can expose sensitive context or create contracts without clear user intent.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README states that the skill reads user project and notes paths and writes contracts, profile, and memory files, but it does not provide a clear privacy warning, consent model, retention description, or data-sharing boundaries. Given that the skill processes potentially sensitive source code, notes, and personal learning profiles, users may unknowingly expose confidential information to the runtime, memory plugins, or related components.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The IM usage section reinforces broad activation phrases such as '我在做 ML 项目' and generic explanation requests like '这个是什么意思', which are common in normal conversation. Because this skill is designed to inspect user project and note paths and persist learning state, ambiguous triggers increase the chance of unintended invocation and privacy-affecting actions.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill advertises and instructs behaviors that require file read/write, shell execution, networking, and environment access, but it does not declare any explicit tool scope or permission boundaries. This creates a least-privilege failure: the skill can access and manipulate local state, launch services, and potentially communicate externally without transparent user-facing authorization constraints.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The manifest description is entirely in Chinese and presents the skill behavior as fixed, with no indication that the user can choose another language. Across the file, all user-facing instructions and trigger examples are Chinese-centric, which implies a language constraint without offering opt-in or alternatives.

Vague Triggers

Medium
Confidence
95% confidence
Finding
Broad everyday triggers like '我在做' and '我想学' can activate the skill during ordinary conversation, causing unintended access to project context, memory, or side-effecting workflows. In a skill with file, shell, and network-adjacent behavior, accidental activation materially increases risk.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The description presents the skill as broadly available for learning help and supervision without clearly constraining when it should be invoked or what user consent boundaries apply. In multi-agent environments, vague invitation language can cause over-triggering, unintended collection of project/code context, or participation in workflows the user did not explicitly authorize.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The manifest explicitly allows accepting another user's supervision invitation and checking that user's learning progress with reminders, but it does not document consent flow, authorization checks, or privacy warnings. Because this is cross-user monitoring, misuse could expose activity metadata or enable unwanted surveillance-like behavior, especially if invitations or bearer tokens are mishandled.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The activation conditions are broad enough that ordinary learning-related phrases can trigger the contract workflow and start soliciting project details and local paths. In this skill’s context, that increases the chance of unintended data collection and persistence before the user clearly understands they are entering a stateful flow.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill requires at least one local code, notes, or document path and states the agent will read those materials, but it does not present a prominent privacy warning about possible exposure of secrets, personal notes, or unrelated files. 'Read-only' does not mitigate confidentiality risk because sensitive data can still be ingested and surfaced.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill instructs the agent to persist user project details, motivations, deadlines, resources, and profile information into multiple files without a clear user-facing disclosure of storage scope, retention, or sensitivity. This creates avoidable privacy risk and can leave durable records of personal or proprietary information on disk.

Ssd 3

Medium
Confidence
94% confidence
Finding
The skill combines collection of local resource paths with persistent storage of user-derived profile and project summaries in plain-language files, increasing the likelihood of privacy leakage, oversharing, and unintended long-term profiling. The context makes this more dangerous because the data is educationally adjacent but may include proprietary code locations, personal notes, motivations, and behavioral preferences.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger '用户主动提问' is broad enough to match ordinary assistance requests, making the skill likely to activate outside a narrowly intended learning-contract context. In practice this can cause over-collection of context, unsolicited state updates, and unexpected pedagogical behavior when the user only wanted a direct answer.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The '心跳' trigger is underspecified, with no clear boundaries for when background prompting should occur. Ambiguous autonomous triggering is risky because it can lead to unsolicited reads of project resources and writes to memory/contract state without a fresh user request.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill tells the user it will access project resources in a read-only way, but in the same workflow it persists data to contract-memory files and updates contract state. Even if the writes target different files than the project resources, this is a scope/transparency problem: users may reasonably infer no stateful side effects beyond reading, while the agent is in fact creating and modifying persistent records tied to their project activity.

Static analysis

No suspicious patterns detected.