Back to skill

Security audit

ve-exchange-rates

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent overall, but it can present fabricated exchange-rate values as successful output when live financial data sources fail.

Review this skill carefully before relying on it for money-related decisions. Its network sources are appropriate, and it does not show credential theft or persistence, but it can output estimated or hardcoded rates when real data is unavailable. Users should treat results as informational only unless the fallback behavior is removed or made fail-closed and clearly machine-readable.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/get_rates.py:102
Finding
Fabricated Financial Rates Returned After Data Retrieval Failures## Vulnerability Details **File Location**: `scripts/get_rates.py`, lines 102–132 **Vulnerability Type**: Unsafe fallback behavior and silent fabrication of financial data **Risk Level**: High ### Vulnerable Code ```python try: bcv_rate_str, date_text, source, date_ok = fetch_bcv() except Exception: try: source = "exchange fallback" bcv_rate_str = fetch_fallback_rate() except Exception: source = "valor de respaldo" bcv_rate_str = "420" print("⚠️ Usando valor de respaldo") bcv_rate = float(bcv_rate_str) print(f"✅ Tasa BCV: {bcv_rate_str} Bs/USD") print(f"🔎 Fuente BCV: {source.replace('https://www.', '').replace('https://', '').rstrip('/')}") if date_text: print(f"📅 Fecha valor BCV: {date_text}") if not date_ok: print("⚠️ Advertencia: la fecha valor BCV no coincide con hoy/mañana") print() print("📊 Consultando USDT Binance P2P...") try: buy_avg, buy_min, buy_max, buy_count = fetch_binance_side("SELL") except Exception: buy_avg = bcv_rate * 1.45 buy_min = bcv_rate * 1.42 buy_max = bcv_rate * 1.48 buy_count = "0 (estimado)" try: sell_avg, sell_min, sell_max, sell_count = fetch_binance_side("BUY") except Exception: sell_avg = bcv_rate * 1.46 sell_min = bcv_rate * 1.43 sell_max = bcv_rate * 1.49 sell_count = "0 (estimado)" ``` ### Technical Analysis The implementation catches every exception raised while retrieving or parsing BCV and Binance data. These broad handlers cover network timeouts, TLS failures, malformed JSON, upstream schema changes, HTML parsing failures, service errors, and programming defects. If both BCV sources fail, the application substitutes a hardcoded exchange rate of `420`. If either Binance request fails, it manufactures P2P prices by multiplying the BCV value by fixed factors. The program then uses these synthetic values to calculate and displa ...[truncated 2484 chars]
Remediation
## Remediation Suggestions 1. Remove the hardcoded BCV rate and all multiplier-based Binance estimates. Financial rates should never be fabricated when authoritative sources are unavailable. 2. Fail closed when live data cannot be obtained. Print a clear error message, omit dependent calculations, and return a nonzero exit status. 3. Catch specific exceptions such as `urllib.error.URLError`, `TimeoutError`, `json.JSONDecodeError`, `KeyError`, and `ValueError` instead of suppressing every `Exception`. 4. Preserve and report the reason each source failed without exposing sensitive implementation details. 5. Represent source status explicitly in machine-readable output, using fields such as `source`, `retrieved_at`, `is_live`, and `error`. 6. If cached data is supported, label it prominently with its original retrieval timestamp and enforce a documented maximum age. 7. Do not calculate gaps or conversions unless both required rates were retrieved successfully and validated as positive, finite numeric values. 8. Update `SKILL.md` to document every fallback behavior and clearly state that unavailable sources produce an error rather than estimated market data. 9. Add tests covering total source failure, malformed HTML, malformed JSON, empty Binance offers, zero or negative rates, and partial-source availability.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (5)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill documentation instructs execution of local shell and Python scripts that perform outbound network access, but the manifest declares no explicit tool scope such as permissions or allowed-tools. This creates an authorization and review gap: an agent or operator may invoke code with shell and network capabilities that are not clearly declared, increasing the chance of unintended external requests or execution of modified local scripts without policy visibility.

External Transmission

Medium
Category
Data Exfiltration
Content
BCV_URL = "https://www.bcv.org.ve/"
BINANCE_URL = "https://p2p.binance.com/bapi/c2c/v2/friendly/c2c/adv/search"
FALLBACK_URL = "https://api.exchangerate-api.com/v4/latest/USD"
UA = "Mozilla/5.0"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The manifest describes a skill for getting Venezuelan exchange rates and calculating the gap between them. While arithmetic is expected, launching the system `bc` binary via `subprocess.check_output` is an unnecessary execution capability that is not justified by the stated purpose and could have been implemented directly in Python.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def bc(expr: str) -> str:
    out = subprocess.check_output(["bc", "-l"], input=(expr + "\n").encode(), stderr=subprocess.DEVNULL)
    return out.decode().strip().splitlines()[-1]
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The script's user-facing strings are hard-coded in Spanish throughout its terminal output, including headings, status messages, warnings, and summaries. This enforces a specific language/locale for all users with no opt-in, override, or documented justification, which matches the language/locale policy violation criteria.

Static analysis

No suspicious patterns detected.