T09 · Insecure Skill Coding Practices
- Location
scripts/fetch_price.py:31- Finding
Generic API_KEY Secret Is Unnecessarily Read and Transmitted to CoinGecko
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a mostly coherent read-only crypto price tool, but its credential handling is under-scoped and unsafe enough to require review before installation.
Review before installing. Use only a dedicated CoinGecko key, do not keep unrelated API_KEY values in the working .env, remove or rotate the published CG-looking key, and avoid running the documented echo commands that reveal the full key. The skill does not show trading, wallet access, persistence, or destructive behavior, but its credential examples and generic secret fallback need correction.
scripts/fetch_price.py:31Generic API_KEY Secret Is Unnecessarily Read and Transmitted to CoinGecko
SKILL.md:127Repository Documentation Contains a Credential-Like Fixed API Key
references/DESCRIPTION.md:487Troubleshooting Instructions Print the Full API Key to the Terminal
This mismatch further indicates the skill performs diagnostics and status reporting, accesses Kraken, and handles key-tier behavior differently from what is advertised. When security review is based on the declared purpose, hidden or inaccurate behavior can bypass user consent and lead to broader data exposure or network activity than intended.
This mismatch further indicates the skill performs diagnostics and status reporting, accesses Kraken, and handles key-tier behavior differently from what is advertised. When security review is based on the declared purpose, hidden or inaccurate behavior can bypass user consent and lead to broader data exposure or network activity than intended.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: coingecko
description: "Live Bitcoin & crypto price data via CoinGecko API. Fetch BTC/USD, ETH/USD, multi-asset quotes. Supports both Demo (free) and Pro API keys. No credentials in prompts—only .env isolation."
version: 1.0.0
author: "bronoman & Hermes local (May 2026)"
license: MIT
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: coingecko
description: "Live Bitcoin & crypto price data via CoinGecko API. Fetch BTC/USD, ETH/USD, multi-asset quotes. Supports both Demo (free) and Pro API keys. No credentials in prompts—only .env isolation."
version: 1.0.0
author: "bronoman & Hermes local (May 2026)"
license: MIT
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: coingecko
description: "Live Bitcoin & crypto price data via CoinGecko API. Fetch BTC/USD, ETH/USD, multi-asset quotes. Supports both Demo (free) and Pro API keys. No credentials in prompts—only .env isolation."
version: 1.0.0
author: "bronoman & Hermes local (May 2026)"
license: MIT
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: coingecko
description: "Live Bitcoin & crypto price data via CoinGecko API. Fetch BTC/USD, ETH/USD, multi-asset quotes. Supports both Demo (free) and Pro API keys. No credentials in prompts—only .env isolation."
version: 1.0.0
author: "bronoman & Hermes local (May 2026)"
license: MIT
The file instructs users to configure their environment using a concrete API key value, which constitutes credential disclosure and encourages unsafe copying of a potentially live secret. In a skill whose stated security model depends on '.env isolation' and not exposing credentials, this contradiction makes the exposure more dangerous, not less.
A hardcoded API credential appears directly in the reference documentation as an environment variable example. Hardcoded secrets in repository content are routinely harvested by automated scanners and can be abused to consume service quotas or access associated API features.
Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.
### Option 3: Paid Pro API (For High-Volume Use)
If you run many agents or need unlimited queries:
1. **Visit:** https://www.coingecko.com/en/api/pricing
2. **Choose tier:** $10/month = most use cases
3. **Add key to .env** (same as Demo)
The skill declares access to environment variables and performs network operations, but it does not define an explicit tool scope such as permissions or allowed-tools. This creates an authorization gap where the runtime may grant broader capabilities than users expect, increasing the chance of unintended credential reads or outbound requests.
Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.
### Pro Key (Paid 💰)
- **Where to get:** https://www.coingecko.com/en/api/pricing
- **Signup:** 5 minutes via API dashboard
- **Limits:** Unlimited calls (enterprise tier available)
- **Endpoint:** Same as Demo, with `x_cg_pro_api_key` param
- **Cost:** $10-50/month depending on tier
- **Best for:** High-volume data pipelines, trading bots, critical services
The setup example uses an environment variable name that contradicts the documented required variable, which can cause users to misconfigure the skill and accidentally place secrets in the wrong location or troubleshooting channels. Misleading credential guidance often leads to ad hoc fixes, copy-pasting secrets, and unintended exposure.
Including a real-looking API key value in documentation normalizes pasting secrets into files and may result in users reusing or exposing live credentials. Even if the sample is not valid, it increases the risk of accidental secret handling mistakes and can trigger unsafe copy-paste behavior into repos or logs.
A hardcoded-looking key in natural-language guidance can be mistaken for a usable credential or copied into persistent configuration, encouraging insecure secret management. This is especially risky in agent ecosystems where users may mirror documentation verbatim into shared files or automation.
The documentation explicitly claims API keys are never shown, yet it includes a concrete CoinGecko API key value in plaintext. Even if the key is intended as an example, publishing a real-looking credential creates immediate risk of unauthorized use, rate-limit exhaustion, and undermines trust in the skill's credential-handling guarantees.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
try:
api_key = get_coingecko_api_key()
url = "https://api.coingecko.com/api/v3/simple/price"
params = {
"ids": ",".join(assets),
"vs_currencies": "usd",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
try:
api_key = get_coingecko_api_key()
url = "https://api.coingecko.com/api/v3/simple/price"
params = {
"ids": ",".join(assets),
"vs_currencies": "usd",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
try:
api_key = get_coingecko_api_key()
url = "https://api.coingecko.com/api/v3/simple/price"
params = {
"ids": ",".join(assets),
"vs_currencies": "usd",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
try:
api_key = get_coingecko_api_key()
url = "https://api.coingecko.com/api/v3/simple/price"
params = {
"ids": ",".join(assets),
"vs_currencies": "usd",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
try:
api_key = get_coingecko_api_key()
url = "https://api.coingecko.com/api/v3/simple/price"
params = {
"ids": ",".join(assets),
"vs_currencies": "usd",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
try:
api_key = get_coingecko_api_key()
url = "https://api.coingecko.com/api/v3/simple/price"
params = {
"ids": ",".join(assets),
"vs_currencies": "usd",
The module advertises BTC/USD pricing, but the Kraken fallback requests XBTUSDT, which is a different market. This can mislead downstream consumers into treating USDT-quoted data as USD, causing incorrect financial decisions or integrity issues in any automation that assumes the documented asset pair is returned.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Fallback: Fetch BTC/USD price from Kraken (public API, no auth).
"""
try:
url = "https://api.kraken.com/0/public/Ticker"
params = {"pair": "XBTUSDT"}
response = requests.get(url, params=params, timeout=timeout)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Fallback: Fetch BTC/USD price from Kraken (public API, no auth).
"""
try:
url = "https://api.kraken.com/0/public/Ticker"
params = {"pair": "XBTUSDT"}
response = requests.get(url, params=params, timeout=timeout)
The manifest describes this skill as providing live crypto price data via the CoinGecko API, including Demo and Pro API key support. This script additionally probes Kraken as a fallback provider, introducing a second external data source and behavior not reflected in the stated skill description.
Detected: suspicious.exposed_secret_literal