Back to skill

Security audit

NOFX AI500 Report

Security checks for vulnerabilities and agentic risk

Overview

The skill is broadly aligned with automated crypto reporting, but it includes scheduled shell automation, unsafe credential handling, and concrete script weaknesses that require review before use.

Install only if you are comfortable with recurring background jobs that call external market APIs and send messages to Telegram. Before use, remove and rotate the embedded NOFX key, require secrets from protected configuration, avoid putting keys in prompts or URLs where possible, fix the monitor.sh path interpolation bug, add an easy cron disable path, and avoid the optional video/TTS pipeline unless its third-party data sharing and dependencies are explicitly approved.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/monitor.sh:6
Finding
Hard-Coded NOFX API Credential Exposed in Source Code and Request URLs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/monitor.sh:6-10`; `references/ai500-report.py:6-7, 14-21` **Vulnerability Type**: Hard-coded credential and sensitive query-string exposure **Risk Level**: High ### Vulnerable Code ```bash KEY="${NOFX_KEY:-cm_568c67eae410d912c54c}" BASE="${NOFX_BASE:-https://nofxos.ai}" KNOWN_FILE="${NOFX_KNOWN_FILE:-$HOME/.openclaw/workspace/nofx-ai500-known.json}" RESPONSE=$(curl -s "${BASE}/api/ai500/list?auth=${KEY}") ``` ```python BASE = "https://nofxos.ai" KEY = "cm_568c67eae410d912c54c" DURATIONS = ["5m", "15m", "30m", "1h", "4h", "8h", "24h"] def curl_json(url): try: r = subprocess.run(["curl", "-s", "-f", url], capture_output=True, text=True, timeout=15) if r.returncode != 0: return None return json.loads(r.stdout) except: return None def nofx(endpoint, params=""): url = f"{BASE}{endpoint}?auth={KEY}" if params: url += f"&{params}" return curl_json(url) ``` ### Technical Analysis A credential-shaped NOFX API key is embedded directly in two distributed project files. In the shell script, the embedded value is used whenever `NOFX_KEY` is absent, while the Python report generator always uses the hard-coded value. Anyone able to download or read the Skill package can recover the credential without executing the Skill. The credential is also transmitted as an `auth` query parameter. Query-string credentials can be exposed through: - Process listings containing the `curl` command line - HTTP client, reverse-proxy, and application access logs - Monitoring and observability systems - Shell debugging output - URL history or diagnostic records Although HTTPS protects the request in transit when certificate verification remains enabled, it does not prevent local process or server-side logging of the complete URL. ### Attack Path 1. An attacker obtains the publicly distributed Skill package or read access to the project directory. 2. Th ...[truncated 1045 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Revoke and rotate the embedded credential immediately. 2. Remove all default credential values from source code: ```bash : "${NOFX_KEY:?NOFX_KEY must be set}" KEY="$NOFX_KEY" ``` 3. Read credentials only from an approved secret manager, protected environment variable, or permission-restricted configuration file. 4. Do not place secrets in cron payload text, generated reports, logs, or error messages. 5. Prefer an HTTP authorization header if the NOFX API supports one: ```bash curl --fail --silent --show-error \ -H "Authorization: Bearer ${NOFX_KEY}" \ "${BASE}/api/ai500/list" ``` 6. If query-string authentication is mandated by the API, ensure process visibility and logs are restricted and redact the `auth` parameter in all telemetry. 7. Add automated secret scanning to CI and reject future credential-shaped literals. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/monitor.sh:7
Finding
Arbitrary Python Code Injection Through NOFX_KNOWN_FILE<![CDATA[ ## Vulnerability Details **File Location**: `scripts/monitor.sh:7, 21-22, 34-50, 57-63` **Vulnerability Type**: Environment-variable-driven source code injection **Risk Level**: High ### Vulnerable Code ```bash KNOWN_FILE="${NOFX_KNOWN_FILE:-$HOME/.openclaw/workspace/nofx-ai500-known.json}" ``` ```bash if [ -f "$KNOWN_FILE" ]; then KNOWN=$(python3 -c "import json; print('\n'.join(json.load(open('$KNOWN_FILE'))))") else KNOWN="" fi ``` ```bash NEW_JSON=$(echo "$RESPONSE" | python3 -c " import sys, json d = json.load(sys.stdin) try: known = set(json.load(open('$KNOWN_FILE'))) except: known = set() new_coins = [c for c in d['data']['coins'] if c['pair'] not in known] json.dump(new_coins, sys.stdout, indent=2) ") # Update known list echo "$RESPONSE" | python3 -c " import sys, json d = json.load(sys.stdin) pairs = [c['pair'] for c in d['data']['coins']] try: old = json.load(open('$KNOWN_FILE')) except: old = [] json.dump(list(set(old + pairs)), open('$KNOWN_FILE', 'w')) " ``` ```bash echo "$RESPONSE" | python3 -c " import sys, json d = json.load(sys.stdin) json.dump([c['pair'] for c in d['data']['coins']], open('$KNOWN_FILE', 'w')) " ``` ### Technical Analysis `NOFX_KNOWN_FILE` is an environment-controlled value. Its content is expanded by the shell directly inside several Python programs passed to `python3 -c`. Shell quoting does not make this safe at the Python language layer. A path containing a single quote and additional Python syntax can terminate the string literal passed to `open(...)`, insert new Python expressions or statements, and comment out the remaining generated source. The injected code then runs with the same identity and environment as the scheduled monitoring process. The `[ -f "$KNOWN_FILE" ]` check limits the first injection point to paths recognized as files, but other vulnerable invocations are reached when new or removed coins are detected. It is not a valid input-sanitization boundary and does not p ...[truncated 1636 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Pass the path as data rather than interpolating it into Python source: ```bash KNOWN=$(python3 - "$KNOWN_FILE" <<'PY' import json import sys with open(sys.argv[1], encoding="utf-8") as handle: print("\n".join(json.load(handle))) PY ) ``` Apply the same pattern to every read and write operation. Additional hardening should include: 1. Resolve the path with `realpath` and require it to remain inside a dedicated state directory. 2. Reject symlinks where they are unnecessary. 3. Create the state directory with restrictive permissions such as `0700`. 4. Create state files with permissions such as `0600`. 5. Write updates atomically to a securely created temporary file and rename it into place. 6. Replace broad `except:` clauses with specific exceptions so corruption and permission failures are not silently ignored. 7. Validate the loaded JSON schema and require every list member to be a string matching the expected trading-pair format. 8. Run the scheduled job under a dedicated, unprivileged account with access only to its required state directory. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:63
Finding
Documentation Recommends Disabling TLS Certificate Verification<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:63-66` **Vulnerability Type**: Insecure TLS configuration guidance **Risk Level**: Medium ### Vulnerable Code ```python import ssl ctx = ssl._create_unverified_context() ``` ### Technical Analysis The setup documentation recommends creating an unverified SSL context when Python has certificate-related problems. `_create_unverified_context()` disables certificate-chain and hostname verification for requests that use that context. Encryption without certificate authentication does not establish that the client is communicating with the legitimate NOFX or Binance server. If a user follows this recommendation, a network intermediary can present an arbitrary certificate and impersonate the requested service. This code is presented as optional guidance and is not used by the currently reviewed shell or Python implementation. The vulnerability becomes active when a user incorporates the recommendation into API request code. ### Attack Path 1. A user encounters a local certificate-store problem and applies the documented workaround. 2. API requests are made using the unverified SSL context. 3. An attacker with a network interception position—such as a malicious proxy, compromised router, hostile Wi-Fi network, or poisoned DNS route—redirects or intercepts the request. 4. The attacker presents an untrusted certificate, which the client accepts because verification is disabled. 5. The attacker reads authentication-bearing requests and can return forged market data. 6. The generated reports or trading suggestions are produced from attacker-controlled responses. ### Impact Assessment The attacker can compromise the confidentiality and integrity of requests made through the insecure context. Potential effects include: - Theft of NOFX API credentials transmitted in URLs - Manipulation of AI500 selections, OI values, fund-flow values, funding rates, or K-line data - Misleading Telegram reports and tradi ...[truncated 261 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `_create_unverified_context()` recommendation. 2. Correct the system trust configuration rather than suppressing verification. 3. Use Python's default verified context: ```python import ssl context = ssl.create_default_context() ``` 4. Install or update the operating system CA bundle when certificates cannot be validated. 5. If a private certificate authority is legitimately required, load only that specific CA: ```python context = ssl.create_default_context(cafile="/path/to/approved-ca.pem") ``` 6. Retain hostname verification and certificate-chain validation. 7. Treat TLS failures as hard errors and avoid silently falling back to insecure transport. ]]>

T08 · Insecure Dependencies

Warning
Location
references/video-pipeline.md:12
Finding
Unpinned Third-Party Package Retrieval and Execution Through npx<![CDATA[ ## Vulnerability Details **File Location**: `references/video-pipeline.md:12` **Vulnerability Type**: Unpinned dependency execution and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```bash npx remotion render CompositionId output.mp4 ``` ### Technical Analysis The optional video pipeline instructs users to execute `remotion` through `npx` without specifying an exact package version, lockfile, integrity constraint, or requirement that a reviewed local installation already exist. Depending on the local npm/npx version and project state, `npx` can resolve and download package code from the configured npm registry when the binary is not installed locally. Package installation and execution may run third-party code, including lifecycle scripts and the requested CLI, with the invoking user's privileges. The reviewed project does not contain a `package.json` or lockfile that would make the resolved Remotion version reproducible. Therefore, the effective code executed by this optional instruction may change after the Skill itself has been audited. ### Attack Path 1. A user follows the optional video-generation instructions on a system without a verified local `remotion` installation. 2. `npx` resolves the package using the current registry configuration and available package versions. 3. A compromised registry account, malicious registry mirror, poisoned dependency, or compromised package release supplies hostile code. 4. `npx` downloads and executes that code. 5. The hostile code runs with the user's privileges and can access files, environment variables, network connectivity, and project artifacts available to that user. ### Impact Assessment A compromised dependency can obtain code execution under the account generating the video. The accessible scope may include: - API keys and messaging credentials stored in environment variables - Report data and generated media in the workspace - User-writable files - Outbound network acce ...[truncated 296 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define dependencies in a committed `package.json`. 2. Pin an audited exact Remotion version rather than using a floating release. 3. Commit the generated lockfile and preserve integrity hashes. 4. Install with a lockfile-enforcing command such as: ```bash npm ci --ignore-scripts ``` If lifecycle scripts are required, review them before enabling them. 5. Invoke the verified local binary: ```bash ./node_modules/.bin/remotion render CompositionId output.mp4 ``` 6. Use a trusted registry and consider registry allowlisting. 7. Run video generation in a sandbox or container without unrelated credentials and with narrowly scoped filesystem access. 8. Periodically audit pinned dependencies before intentionally updating them. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The documented behavior presents the skill as a broad market-report generator, but the referenced behavior includes monitoring, change detection, cron automation, and local state persistence not clearly disclosed in the description. That mismatch is security-relevant because users may authorize the skill expecting passive reporting while it actually performs ongoing automated actions and stores data locally.

Missing User Warnings

High
Confidence
96% confidence
Finding
The skill asks for an API auth key and says NOFX endpoints use `?auth=KEY` query parameters, while also suggesting passing the key via environment variables, without warning about exposure in logs, process listings, shell history, cron definitions, proxies, or server access logs. Query-string credentials are especially sensitive because they are commonly recorded by intermediaries and observability systems, making credential leakage likely if the setup is used as written.

External Script Fetching

High
Category
Supply Chain
Content
BASE="${NOFX_BASE:-https://nofxos.ai}"
KNOWN_FILE="${NOFX_KNOWN_FILE:-$HOME/.openclaw/workspace/nofx-ai500-known.json}"

RESPONSE=$(curl -s "${BASE}/api/ai500/list?auth=${KEY}")

CURRENT=$(echo "$RESPONSE" | python3 -c "
import sys, json
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill directs the agent to create cron jobs and run `scripts/monitor.sh` via exec, which implies shell execution and likely local state/file writes, yet it declares no `permissions` or `allowed-tools` scope. This under-specification is dangerous because consumers and enforcement layers cannot accurately constrain what the skill is allowed to do, increasing the chance of unintended command execution or filesystem modification.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The activation text is broad enough to match common requests for crypto updates, alerts, or summaries, which can cause the skill to trigger in situations where the user did not intend to enable recurring monitoring or message delivery. In this context, over-broad invocation is risky because the skill requests credentials and sets up automated external communications.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill instructs users to set up repeated polling of external APIs and automated delivery to Telegram or other messaging targets, but it does not clearly warn that this creates ongoing outbound transmissions and repeatedly shares destination identifiers. In a crypto-reporting context, this increases the risk of unintended data egress, misdelivery to the wrong channel, and silent background activity continuing after initial setup.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The file contains a hardcoded API key and automatically sends it to the NOFX service on every request. Embedding credentials in source code makes them recoverable by anyone with code access and enables unauthorized reuse of the key, quota abuse, and potential access to associated account data or billing.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill silently transmits an embedded authentication token in outbound requests without clear user awareness. This combines secret exposure with undisclosed credential use, increasing the chance of misuse, accidental redistribution, and trust violations for anyone deploying the skill.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def curl_json(url):
    try:
        r = subprocess.run(["curl", "-s", "-f", url], capture_output=True, text=True, timeout=15)
        if r.returncode != 0:
            return None
        return json.loads(r.stdout)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The template directs the agent to execute a shell script (`bash <skill-dir>/scripts/monitor.sh`) as part of an automated cron-driven workflow. That expands the skill from report generation into arbitrary local command execution, which is risky because the script path, script contents, or surrounding environment could be modified to run unintended commands without further user review.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The template embeds API connection details and a key placeholder directly inside the agent message payload (`API Base: <BASE> Key: <KEY> Auth: ?auth=KEY`). Placing secrets in prompt text increases the chance of accidental exposure through logs, transcripts, debugging output, or downstream tool use, especially in an automated scheduled job.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The markdown instructs command execution but provides no explicit warning that enabling this monitor causes the agent to run a local shell script on a schedule. In an automation context, lack of disclosure increases the risk that operators enable a capability with system-side effects they did not fully understand.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The template includes handling of sensitive API credentials but does not warn users about secure storage, exposure risks, or the insecurity of placing keys in prompts and URL query parameters. This omission can lead to unsafe operational practices and secret leakage in logs or message history.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The cron payload explicitly instructs the agent to send the generated market report to Telegram via a message tool, but it provides no user-facing warning, approval step, or data-classification guard before external transmission. In an automated reporting skill, this creates a real risk of unintended disclosure of report contents, API-derived intelligence, or future inclusion of sensitive configuration/runtime data to a third-party messaging platform.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding
Using `npx remotion render` without pinning an exact package version makes the build depend on whatever version `npx` resolves at runtime. That creates a supply-chain risk: a malicious or compromised upstream release could execute unexpected code during report generation, especially because npm packages commonly run install-time or CLI code locally.

Context-Inappropriate Capability

Medium
Confidence
78% confidence
Finding
The documented TTS integration sends report narration content to a third-party provider, which expands the skill from local report generation into external content transmission. Even if intended for voice narration, this broadens the data exposure surface and introduces dependency on an outside service not clearly scoped in the skill description.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The TTS example transmits `narration_text` to `api.minimax.chat` with no privacy notice, consent flow, or guidance on what data is safe to include. If generated reports ever contain proprietary trading notes, internal commentary, or user-specific content, this could leak sensitive information to a third party without user awareness.

External Transmission

Medium
Category
Data Exfiltration
Content
"voice_setting": {"voice_id": "cute_girl", "speed": 1.0, "vol": 1.0, "pitch": 0},
    "audio_setting": {"sample_rate": 32000, "bitrate": 128000, "format": "mp3"}
}
# POST to https://api.minimax.chat/v1/t2a_v2
# Response: data.data.audio (hex-encoded MP3)
```
Confidence
94% confidence
Finding
The endpoint `https://api.minimax.chat/v1/t2a_v2` is an explicit external transmission path for generated narration content. In a market-intelligence skill, outbound transfer of generated text can expose proprietary analysis or operational details, making this more sensitive than generic public-content processing.

Context-Inappropriate Capability

Medium
Confidence
77% confidence
Finding
The manifest describes producing AI500 market reports and Telegram/message summaries, but this file adds a separate media-processing workflow requiring local command-line execution via ffmpeg. Shell-driven video rendering/assembly is not an obvious or declared requirement for a report-generation skill focused on crypto signal monitoring.

Context-Inappropriate Capability

Medium
Confidence
99% confidence
Finding
The script embeds a default API credential directly in source via `NOFX_KEY:-cm_568c67eae410d912c54c`, which exposes the credential to anyone who can read the skill or repository. Hardcoded secrets are commonly reused, copied into logs, or accidentally committed, enabling unauthorized API use and making secret rotation difficult.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The script sends the API credential as a URL query parameter in a `curl` request, which can leak through shell history, process listings, proxy logs, web server logs, and monitoring systems even when HTTPS is used. In this case the risk is elevated because the credential may also be the hardcoded default secret from line 6.

Missing User Warnings

Low
Confidence
83% confidence
Finding
The script makes multiple HTTP requests to external services using subprocess-invoked curl, including to NOFX and Binance endpoints. Although the module docstring says it fetches real data via curl, there is no runtime notice, confirmation, or more specific disclosure about contacting third-party services and transmitting requested symbols and auth parameters.

Natural-Language Policy Violations

Low
Confidence
72% confidence
Finding
The natural-language guidance hard-codes a specific voice setting for narration rather than presenting it as a selectable option. This can constitute a language/locale-style policy issue when user-facing presentation attributes are forced without opt-in or alternative choices.

Missing User Warnings

Low
Confidence
87% confidence
Finding
The script updates the local state file by opening KNOWN_FILE for writing, which modifies user data on disk. Aside from an inline comment, there is no user-facing notice, confirmation, or descriptive warning that running the script will create or overwrite the known-coins file.

Missing User Warnings

Low
Confidence
86% confidence
Finding
In the removed-coins path, the script rewrites KNOWN_FILE with the current remote list, which is a file write affecting persistent local state. The script does not provide a user-facing warning or clear disclosure that this overwrite will occur.

Static analysis

No suspicious patterns detected.