Back to skill

Security audit

Enso Tracker

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real ENSO and weather charting skill, but it needs review because it stores an API key in a weakly protected file and can produce misleading simulated analysis when real data is unavailable.

Install only after reviewing the data-integrity and credential-storage tradeoffs. Prefer a virtual environment with pinned dependencies, keep the OpenWeatherMap key outside the skill directory or lock config.json to user-only permissions, and treat anomaly/correlation charts as unreliable whenever the tool reports that it used simulated data.

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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
sources.py:213
Finding

Berkeley Earth Data Is Retrieved Over Plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: sources.py:213-222
Vulnerability Type: Plaintext transport of externally sourced scientific data
Risk Level: Medium

Vulnerable Code

python
region_lower = region.lower().replace(' ', '-')
url = f"http://berkeleyearth.lbl.gov/regions/{region_lower}.txt"

try:
    print(f"📊 正在获取 Berkeley Earth {region} 温度异常数据...")
    req = urllib.request.Request(
        url,
        headers={'User-Agent': 'OpenClaw-ENSO-Tracker/1.0'}
    )

    with urllib.request.urlopen(req, timeout=10) as response:
        data = response.read().decode('utf-8')

Technical Analysis

Historical temperature data is downloaded over unencrypted HTTP. HTTP provides neither server authentication nor response integrity, allowing an attacker with a privileged network position to intercept and modify the response.

The response is parsed as trusted temperature anomaly data and used directly to generate anomaly and ENSO correlation charts. There is no integrity check, response-size limit, strict schema validation, or plausible-range validation before the data influences the output.

Although the request does not transmit an API key or other credential, read-only data can still be security-relevant when its integrity affects analytical conclusions.

Attack Path

  1. A user runs the anomaly or correlate command.
  2. The Skill requests regional data from http://berkeleyearth.lbl.gov/....
  3. An attacker controlling a network gateway, proxy, DNS path, or untrusted wireless network intercepts the plaintext request.
  4. The attacker returns forged or malformed temperature records.
  5. The parser accepts syntactically valid attacker-supplied numeric values.
  6. The Skill generates charts and analyses using the manipulated records.

Impact Assessment

The attacker does not gain local code execution or additional operating-system privileges through the demonstrated path. Howeve ...[truncated 334 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the HTTP endpoint with an official HTTPS endpoint.
  2. Reject redirects that downgrade from HTTPS to HTTP and verify the final response URL.
  3. Limit the maximum response size before reading it into memory.
  4. Validate the content type and expected text encoding.
  5. Enforce a strict record schema and plausible ranges for years, months, and anomaly values.
  6. Where available, verify downloaded data using a publisher-provided checksum or signature.
  7. Fail clearly when authentic data cannot be obtained rather than silently substituting simulated data in analytical output.

T09 · Insecure Skill Coding Practices

Warning
Location
sources.py:20
Finding

OpenWeatherMap API Key Is Stored in an Insufficiently Protected Skill-Local File

Content
View full analysis

Vulnerability Details

File Locations: sources.py:20-36; SKILL.md:52-60; SKILL.md:205-206
Vulnerability Type: Insecure plaintext secret storage and unsupported version-control exclusion claim
Risk Level: Medium

Vulnerable Code

python
SKILL_DIR = Path(__file__).parent.expanduser().absolute()
CONFIG_PATH = SKILL_DIR / "config.json"

def load_config() -> Optional[Dict[str, str]]:
    """
    Load configuration from config.json.

    Returns:
        Dict with config values, or None if not configured.
    """
    try:
        with open(CONFIG_PATH, 'r', encoding='utf-8') as f:
            config = json.load(f)
            return config

The documented setup writes the credential directly into the Skill directory:

bash
mkdir -p ~/.openclaw/workspace/skills/enso-tracker
cat > ~/.openclaw/workspace/skills/enso-tracker/config.json << 'EOF'
{
  "openweather_api_key": "YOUR_API_KEY_HERE"
}
EOF

The documentation also states that the file is excluded through .gitignore, but no .gitignore was present in the audited project.

Technical Analysis

The API key is stored as plaintext within the Skill package directory. The setup procedure does not apply restrictive permissions such as mode 0600, and the implementation does not verify that the file is owned by the current user or inaccessible to other users.

Keeping secrets inside the project tree increases the chance that they will be included in a repository commit, archive, backup, Skill package, or shared directory. The missing .gitignore makes the documentation's claimed version-control protection ineffective in the supplied project.

In addition, the module self-test prints the first eight characters of the configured key at sources.py:328. While this is only a partial disclosure, secret material should not be printed.

Attack Path

  1. A user follows the setup instructions and creates config.json ...[truncated 1049 chars]
Remediation
View remediation

Remediation Suggestions

  1. Store the key outside the Skill source tree, such as in a platform-specific user configuration directory or an approved secret manager.
  2. Prefer an environment variable or OpenClaw-provided secret mechanism when available.
  3. If a file is required, create it with mode 0600 and verify its ownership and permissions before loading it.
  4. Add an actual .gitignore entry for config.json, while noting that ignore rules do not protect files already committed.
  5. Add automated secret scanning to the release and repository workflow.
  6. Remove the API-key prefix from the sources.py self-test output.
  7. Document key revocation and rotation procedures for users who may have exposed the file.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:232
Finding

Third-Party Python Dependencies Are Installed Without Version or Integrity Pinning

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:232
Vulnerability Type: Unpinned third-party dependency installation
Risk Level: Medium

Vulnerable Code

bash
pip install pandas matplotlib numpy scipy

Technical Analysis

The documented installation command resolves mutable latest versions of four packages and their transitive dependencies. It supplies no reviewed version constraints, lock file, package hashes, or explicit trusted package index.

These are established package names rather than apparent typosquatting attempts, and the audit found no evidence that the Skill intentionally installs a malicious package. Nevertheless, an unpinned installation prevents reproducible dependency review and exposes future installations to compromised releases, dependency changes, and incompatible package updates.

Python source distributions may execute build-backend code during installation. Installed packages also execute their module code when imported by the Skill.

Attack Path

  1. A user follows the dependency installation command from SKILL.md.
  2. pip resolves the latest available package versions and transitive dependencies at that time.
  3. A compromised upstream release, malicious transitive dependency, or untrusted package-index response is selected.
  4. Package build code may execute during installation, or malicious code executes when enso_tracker.py imports the installed package.
  5. That code runs with the operating-system privileges of the user performing the installation or running the Skill.

Impact Assessment

If dependency resolution is compromised, attacker-controlled package code could access files, environment variables, API credentials, and network resources available to the installing or executing user. If the installation is performed with elevated privileges, the impact could extend system-wide.

The vulnerability is a supply-chain exposure rather than evidence that t ...[truncated 46 chars]

Remediation
View remediation

Remediation Suggestions

  1. Provide a reviewed lock file or requirements file with exact versions.
  2. Use hash verification, such as pip install --require-hashes -r requirements.txt.
  3. Pin all transitive dependencies, not only the four direct dependencies.
  4. Configure an explicitly trusted package index and require TLS certificate verification.
  5. Regularly scan pinned dependencies for known vulnerabilities and update them through a controlled review process.
  6. Install dependencies in an isolated virtual environment without administrative privileges.
  7. Consider generating and distributing a software bill of materials for released versions of the Skill.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • 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 (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented purpose understates operational behavior: the skill uses external APIs, persists configuration, writes output files, and may perform behavior not clearly disclosed in the summary. Misdescribed behavior undermines informed consent and security review, and hidden fallback/simulated data can mislead users while privileged actions still occur on the host.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill documents file access and multiple outbound network interactions but does not declare any explicit tool scope or permissions. This creates a transparency and policy-enforcement gap: an agent or reviewer may treat the skill as less privileged than it really is, increasing the chance of unintended file reads or network use during activation.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The skill instructs users to store an API key in a persistent config file under the home directory, creating session persistence of sensitive credentials. While common, this increases exposure if local files are later read by other tools, accidentally backed up/shared, or left with weak filesystem permissions.

Content

Scanner excerpt · SKILL.md (reported line 51)May include surrounding context.

  1. Sign up: Visit https://openweathermap.org/api and click "Sign Up"
  2. Get your key: After logging in, go to "API Keys" and copy your key
  3. Create config file:
bash
mkdir -p ~/.openclaw/workspace/skills/enso-tracker

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The usage example maps the plain-language request "What are the hottest cities in the world right now?" directly to skill invocation without documenting any narrower activation boundary. In a markdown skill description, this kind of general everyday phrasing can act as an overly broad trigger unless the file also specifies exclusions or constrained invocation contexts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code presents user-facing output in Chinese by default, and the broader CLI help text and subcommand help strings are also written in Chinese. The skill only offers language choice for chart output via --lang, not for the CLI interface itself, so users are effectively forced into a specific language without explicit opt-in.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The correlate command silently falls back to randomly generated heat records when Berkeley Earth data is unavailable, yet still presents the output as an ENSO-to-heat correlation chart. In a data-analysis skill, this is integrity-impacting because users may mistake fabricated values for real evidence and make decisions based on false analytical output.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The anomaly command generates random placeholder anomaly values when real regional data cannot be fetched, but still proceeds to emit a normal-looking anomaly chart. This is a data provenance and misleading-output issue: the skill claims to analyze regional temperature anomalies but may instead produce synthetic results without strong disclosure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The compare command is described as comparing temperature data between two years, but the implementation actually compares ONI ENSO index values instead. This mismatch can mislead users about what is being analyzed, causing incorrect interpretation of the output and undermining trust in the tool's results.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · sources.py (reported line 23)May include surrounding context.

python
SKILL_DIR = Path(__file__).parent.expanduser().absolute()
CONFIG_PATH = SKILL_DIR / "config.json"
ONI_URL = "https://www.cpc.ncep.noaa.gov/data/indices/oni.ascii.txt"
OPENWEATHER_CURRENT_URL = "https://api.openweathermap.org/data/2.5/weather"
BERKELEY_BASE_URL = "http://berkeleyearth.org/data"

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This Python file contains user-facing setup and error messages entirely in Chinese, which imposes a specific language on users. The file does not offer language selection or explain that the skill is intentionally Chinese-only, so it violates the language/locale policy criterion.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Multiple progress, success, and error strings across network-fetch functions are emitted only in Chinese. Because the skill does not provide a locale option or clearly document a justified region-specific language requirement, these strings constitute a natural-language policy violation.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The example "Is it El Niño or La Niña right now?" is a natural conversational question that could arise in general chat, but the document does not clarify when this should invoke the skill versus receive a normal assistant response. Because no exclusion conditions or trigger constraints are provided, the activation boundary remains underspecified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code creates parent directories and saves generated chart files to the filesystem, but it does not disclose whether existing files may be overwritten or that directories may be created automatically. Although file output is part of the skill's purpose, there is no visible warning about the side effects of writing to arbitrary user-provided paths.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code defaults the lang parameter to zh and later emits Chinese titles, labels, legends, and console messages unless the caller overrides it. That creates a locale preference baked into the skill behavior rather than offering a neutral default or explicit user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The label 危险阈值 ... is always rendered in Chinese even though the function accepts a lang parameter intended to support both Chinese and English. This violates language-choice expectations because users selecting English still receive Chinese output.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The phase-band labels 厄尔尼诺 and 拉尼娜 are fixed Chinese strings even though the function takes a lang argument and localizes other strings. Users expecting English output would still see Chinese legend entries.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The custom legend always includes Chinese labels such as 厄尔尼诺, 拉尼娜, and 极端高温, despite the function accepting a language parameter. This creates inconsistent localization and forces a specific language in user-visible output.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.