Back to skill

Security audit

Valuation Calculator

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stock-valuation purpose, but it unnecessarily lets files in the OpenClaw workspace impersonate a Python dependency when the skill runs.

Review this skill before installing. It appears to be a local stock valuation helper, but install it only in an environment where the OpenClaw workspace is trusted, remove the sys.path workspace insertion, and use pinned dependencies. Be aware that the all-holdings mode reads your local holdings.md financial data.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T07 · Tool Hijacking and Spoofing

Error
Location
valuation.py:9
Finding
User-Writable Python Import Path Enables Dependency Hijacking## Vulnerability Details **File Location**: `valuation.py`, lines 9–14 **Vulnerability Type**: Python module search-path hijacking **Risk Level**: High **Vulnerable Code**: ```python # Add workspace to path sys.path.insert(0, os.path.expanduser('~/.openclaw/workspace')) try: import yfinance as yf except ImportError: print("Error: yfinance not installed. Run: pip install yfinance") ``` ### Technical Analysis The program prepends `~/.openclaw/workspace` to `sys.path` before importing the third-party `yfinance` package. Python searches entries in `sys.path` in order, so a file named `yfinance.py` or a directory named `yfinance` within that workspace takes precedence over the legitimate installed dependency. The workspace is also used for ordinary user-managed data such as `holdings.md` and may be writable by the user, another Skill, or another process operating in the shared Agent workspace. No Python modules from this directory are required by the audited script, making the path modification unnecessary. An attacker with write access to the workspace can exploit this behavior without altering the audited project itself. Malicious top-level statements in a spoofed module execute immediately when the import occurs. ### Attack Path 1. The attacker gains the ability to create files in `~/.openclaw/workspace`, potentially through another Skill or process sharing that workspace. 2. The attacker creates `~/.openclaw/workspace/yfinance.py` or a malicious `yfinance/` package. 3. A user invokes `valuation.py`. 4. The script inserts the attacker-writable workspace at index zero of `sys.path`. 5. Python resolves `import yfinance as yf` to the attacker's module instead of the legitimate package. 6. The attacker's top-level Python code executes with the privileges and environment of the user running the Skill. ### Impact Assessment Successful exploitation provides arbitrary Python code execution under the Agent ...[truncated 479 chars]
Remediation
## Remediation Suggestions 1. Remove the workspace path modification because this script does not import any modules from the workspace: ```python try: import yfinance as yf except ImportError: print("Error: yfinance is not installed.") sys.exit(1) ``` 2. Continue accessing `holdings.md` through its explicit filesystem path rather than adding its parent directory to Python's module search path. 3. If local modules become necessary, package them with the project or place them in a dedicated trusted directory with restrictive ownership and permissions. 4. Do not prepend user-writable or shared data directories to `sys.path`. 5. Run the Skill with least privilege and restrict write access to directories containing executable Python modules. 6. Consider launching Python with isolated import settings where operationally appropriate, and verify that dependencies resolve from the expected environment.

T08 · Insecure Dependencies

Warning
Location
valuation.py:11
Finding
Unpinned Third-Party Dependency Installation Guidance## Vulnerability Details **File Location**: `valuation.py`, lines 11–15 **Vulnerability Type**: Unpinned and non-reproducible dependency installation **Risk Level**: Medium **Vulnerable Code**: ```python try: import yfinance as yf except ImportError: print("Error: yfinance not installed. Run: pip install yfinance") sys.exit(1) ``` The dependency is also identified without a reviewed version or lockfile in `SKILL.md`: ```markdown ## Data Source Yahoo Finance API (yfinance) ``` ### Technical Analysis The error message instructs users to install `yfinance` directly from the package index without a version constraint, dependency lockfile, or integrity hashes. Consequently, installation resolves whatever package and transitive dependency versions are current at that time. This creates a non-reproducible supply-chain boundary. A future compromised release, compromised transitive dependency, or unexpected incompatible update could introduce malicious or unsafe behavior without any corresponding change to the audited Skill. Python packages may execute code during installation and will execute module-level code when imported. The reviewed source does not itself download or execute a remote payload. Exploitation depends on compromise or unsafe modification of the package distribution chain and on a user following the displayed installation instruction. ### Attack Path 1. A malicious or compromised version of `yfinance`, or one of its transitive dependencies, becomes available through the package source used by `pip`. 2. A user runs the Skill without `yfinance` installed and receives the recommendation to execute `pip install yfinance`. 3. The user follows that instruction without a reviewed version constraint or hash verification. 4. `pip` resolves and installs mutable package-index content. 5. Malicious package code executes during installation or when `valuation.py` subsequently imports `yfinance` ...[truncated 654 chars]
Remediation
## Remediation Suggestions 1. Add a reviewed dependency manifest with an explicit `yfinance` version. 2. Lock all transitive dependencies to produce reproducible installations. 3. Record and enforce package hashes where supported, for example: ```bash python -m pip install --require-hashes -r requirements.txt ``` 4. Replace the unrestricted installation message with instructions referencing the project's reviewed dependency file: ```python print("Error: dependencies are missing. Install the reviewed requirements with: " "python -m pip install --require-hashes -r requirements.txt") ``` 5. Regularly update pinned dependencies through a controlled review process that includes vulnerability and provenance checks. 6. Install dependencies in a dedicated virtual environment under a non-privileged account rather than modifying a global Python environment.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill documentation states it reads from a local file (`~/.openclaw/workspace/holdings.md`), which implies file-read capability, but the manifest declares no explicit tool scope such as `permissions` or `allowed-tools`. Missing least-privilege scoping can cause the agent runtime to grant broader-than-necessary access or leave access expectations ambiguous, increasing the risk of unintended local file exposure if the implementation or platform defaults are permissive.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This Python skill presents its title, docstrings, usage text, and formatted output in Traditional Chinese, which imposes a specific language on users by default. The file does not indicate that the language is configurable or limited to a justified region-specific context, so it conflicts with the language/locale policy described for this audit.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The skill reads a local workspace file (`~/.openclaw/workspace/holdings.md`) and, when invoked as `value` with no further arguments, automatically processes the user's portfolio. That expands access beyond the explicitly supplied ticker input and can expose sensitive financial holdings from local files, which is a privacy and scope-creep issue even though the data is only used locally in this script.

Intent-Code Divergence

Low
Confidence
97% confidence
Finding
The code retrieves info['profitMargins'], which in yfinance represents profit margin, not gross margin. Later output text states '營收成長+毛利率' and labels the displayed metric as '毛利率', actively misdescribing the calculation presented to the user.