T09 · Insecure Skill Coding Practices
- Location
mtf_momentum.py:245- Finding
Trading API key can be transmitted to an arbitrary environment-controlled endpoint
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This trading bot mostly matches its stated purpose, but it needs review because its API key can be sent to an environment-controlled endpoint and its trading SDK dependency is unpinned.
Install only if you trust the publisher and can run it in a restricted environment. Use a least-privileged Simmer API key, do not set SIMMER_API_URL unless it is the official HTTPS endpoint, pin or review simmer-sdk before installation, start in paper mode, and enable --live only with clear trade limits and monitoring.
mtf_momentum.py:245Trading API key can be transmitted to an arbitrary environment-controlled endpoint
clawhub.json:7Security-sensitive third-party SDK is installed without version or artifact pinning
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
url = f"{BINANCE_KLINE_URL}?symbol={symbol}&interval={interval}&limit={limit}"
try:
req = Request(url, headers={"User-Agent": "SimmerMTFMomentum/1.0"})
data = json.loads(urlopen(req, timeout=10).read())
return data
except Exception as e:
print(f" Binance kline fetch failed: {e}")
The request target is derived from SIMMER_API_URL, an environment variable, and the code also attaches the SIMMER_API_KEY as a Bearer token. If an attacker can influence the environment, they can redirect this request to an arbitrary host and exfiltrate the API key, which is especially dangerous in an automated trading skill.
f"{SIMMER_API_URL}/api/sdk/fast-markets?asset={ASSET}&window=5m&limit=10",
headers={"Authorization": f"Bearer {api_key}"},
)
data = json.loads(urlopen(req, timeout=10).read())
return data.get("markets", [])
except Exception as e:
print(f" Failed to fetch fast markets: {e}")
The documented purpose centers on momentum trading logic, but the skill also advertises portfolio, position, and status interactions that imply access to sensitive account data not clearly disclosed in the main description. This mismatch undermines informed consent and can cause users to authorize a trading skill that also reads account state beyond what they reasonably expect.
The skill documents capabilities that require environment access and network access but does not declare any explicit tool scope or permission boundaries. In an agent setting, missing scope declarations can lead to overbroad execution privileges and make it harder for operators to understand or constrain what the skill may access.
The skill provides a direct path from dry run to '--live' execution without a prominent warning that this may place real-money trades and cause irreversible financial loss. In a trading context, weak safety messaging materially increases the chance of accidental live execution, especially when the instructions are simple and action-oriented.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
SLIPPAGE_MAX_PCT = 0.15
SIMMER_API_URL = os.environ.get("SIMMER_API_URL", "https://api.simmer.markets")
BINANCE_KLINE_URL = "https://api.binance.com/api/v3/klines"
# ---------------------------------------------------------------------------
# SimmerClient singleton
The code emits a fallback automaton report unconditionally whenever AUTOMATON_MANAGED is set, even after the strategy may already have printed a real report. This can produce contradictory status output such as reporting both executed trades and a final no_signal result, which can corrupt downstream automation, monitoring, or control logic in an automated trading environment.
The manifest description explains the skill's purpose in broad marketing language but does not specify concrete invocation phrases, scope limits, or when the skill should not be used. For a markdown/manifest file, this can create ambiguous activation behavior if the description is used for skill routing or discovery.
The manifest and module description present this as a trading strategy that reads Binance data and trades Polymarket fast markets. In addition to that core behavior, the file exposes a --set path that updates and saves configuration to disk, which is a separate state-modifying capability not described in the stated purpose.
A momentum trading skill would be expected to fetch market data, evaluate signals, and optionally place trades. Writing updated settings to a config file is an auxiliary capability that is not mentioned in the manifest description and is not obviously required for executing the strategy itself.
The module docstring says the script provides 'Quick status' and 'Shows active positions and recent signals,' but the implementation also retrieves and displays overall portfolio balance via client.get_portfolio(). Portfolio-level account balance is adjacent functionality, but it is broader than the narrow behavior described in the file documentation.
No suspicious patterns detected.