Back to skill

Security audit

Btc Sprint Stack

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real BTC trading bot, but it bundles under-disclosed wallet, credential, live-account, and self-tuning behaviors that require careful review before use.

Review this before installing, especially if you would run it in live mode or on a machine with wallet keys, Codex auth, Google ADC, or LLM API keys. Use an isolated environment, avoid custom LLM_BASE_URL values unless you provide a dedicated proxy credential, start with dry-run only, and do not expose WALLET_PRIVATE_KEY unless you intentionally want wallet linkage and token approvals performed by the bot.

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

T09 · Insecure Skill Coding Practices

Error
Location
modules/btc_llm_decider.py:155
Finding

Provider credentials can be transmitted to an arbitrary environment-configured LLM endpoint

Content
View full analysis
None: self.provider_name = provider_name self.model_name = model_name self.api_key = api_key self.base_url = (base_url or DEFAULT_OPENAI_BASE_URL).rstrip('/') def complete(self, *, system_prompt: str, user_prompt: str) -> str: body = { 'model': _request_model_name(self.provider_name, self.model_name), 'max_tokens': MAX_MODEL_OUTPUT_TOKENS, 'messages': [ { 'role': 'system', 'content': system_prompt, }, { 'role': 'user', 'content': user_prompt, }, ], 'response_format': { 'type': 'json_schema', 'json_schema': { 'name': 'btc_trade_decision', 'schema': STRICT_SCHEMA, 'strict': True, }, }, } for attempt_index, backoff_seconds in enumerate((0, *LLM_429_BACKOFF_SECONDS)): if backoff_seconds: time.sleep(backoff_seconds) try: raw = _post_json( f'{self.base_url}/chat/completions', body=body, headers={ 'Authorization': f'Bearer {self.api_key}', 'Content-Type': 'application/json', }, ) ``` The same request mechanism is used with a Codex OAuth credential: ```python class CodexOAuthProvider: provider_name = 'c ...[truncated 5221 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
modules/btc_position_manager.py:12
Finding

Source and skill identifier mismatch can bypass the configured open-position limit

Content
View full analysis
list: scoped = [] for position in positions: source = _safe_get(position, 'source') if source and source != skill_slug: continue if (_safe_get(position, 'shares', 0.0) or 0.0) <= 0: continue scoped.append(position) return scoped ``` The position count is then used to enforce the configured limit: ```python scoped_positions = active_positions_for_skill(positions, skill_slug) if len(scoped_positions) >= config['max_open_positions']: reasons.append('max_open_positions_reached') ``` However, the entrypoint deliberately submits a source value that differs from the Skill slug: ```python execution = execute_trade( client, market_id=market.id, side=validated_decision['action'], amount=risk_state['trade_amount_usd'], signal=signal, regime=regime, live=not dry_run, source='btc_sprint_stack.llm', skill_slug=config['skill_slug'], venue='polymarket', validate_real_path=validate_real_path, llm_decision=validated_decision, ) ``` The executor passes both distinct values to Simmer: ```python trade = client.trade( market_id=market_id, side=side, amount=amount, venue=venue, reasoning=reasoning, source=source, skill_slug=skill_slug, signal_data=signal_data, ) ``` The default slug is: ```json { "skill_slug": "btc-sprint-stack" } ``` Therefore, the submitted source is `btc_sprint_stack.llm`, while the value used for position matching is `btc-sprint-stack`. ### Technical Analysis R ...[truncated 2716 chars]
Remediation
View remediation
list: scoped = [] for position in positions: position_slug = _safe_get(position, 'skill_slug') if position_slug != skill_slug: continue if float(_safe_get(position, 'shares', 0.0) or 0.0) <= 0: continue scoped.append(position) return scoped ``` 2. If the SDK does not return `skill_slug`, define and consistently use one canonical source identifier for both trade submission and position matching. 3. Avoid treating positions with missing ownership metadata as implicitly belonging to the Skill. Instead, select an explicit fail-safe policy and document it. 4. Add integration tests that: - Submit a trade through `execute_trade()`. - Feed the resulting position metadata back into `active_positions_for_skill()`. - Confirm the position is counted. - Confirm trading is rejected when `max_open_positions` is reached. 5. Add tests covering positions from other Skills so their positions are neither incorrectly counted nor allowed to obscure this Skill's exposure. 6. Consider enforcing an account-wide concurrent-position or total-exposure cap in addition to Skill-specific accounting. 7. Log the identifiers used for risk scoping and fail closed in live mode if required ownership fields are unavailable or inconsistent. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (26)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is advertised as an active trading operator, but the reported behavior is retrospective log/config analysis with additional local file reads not implied by the description. This mismatch is risky because it can cause users to approve file-accessing analysis behavior they did not intend, and it undermines trust in the skill's stated operating boundaries.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill is advertised as an active trading operator, but the reported behavior is retrospective log/config analysis with additional local file reads not implied by the description. This mismatch is risky because it can cause users to approve file-accessing analysis behavior they did not intend, and it undermines trust in the skill's stated operating boundaries.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is advertised as an active trading operator, but the reported behavior is retrospective log/config analysis with additional local file reads not implied by the description. This mismatch is risky because it can cause users to approve file-accessing analysis behavior they did not intend, and it undermines trust in the skill's stated operating boundaries.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill includes functionality to link an external Polygon wallet and set token approvals using a private key, which is a privileged on-chain capability beyond simple market decisioning. If enabled, this expands the blast radius from trading actions to wallet-level state changes and token allowance operations, creating substantial risk of unauthorized approvals or asset exposure if the environment or downstream SDK behavior is compromised.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

On startup, if live mode is enabled and WALLET_PRIVATE_KEY is present, the skill automatically performs wallet linkage and approval operations with no user-facing disclosure or runtime confirmation. Triggering privileged blockchain actions merely from environment state is dangerous because secrets commonly exist in automation environments, and their presence should not implicitly authorize irreversible wallet changes.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
87% confidence
Finding

The Google OAuth provider obtains fresh cloud-platform scoped access tokens from Application Default Credentials on the host. Using host ADC inside a skill broadens access to ambient credentials that may grant much more than model inference, and the scope shown is wide. In a trading skill context, accessing general cloud credentials is riskier because compromise of the module or prompt path could combine trading actions with unrelated cloud-account access.

Content

Scanner excerpt · modules/btc_llm_decider.py (reported line 226)May include surrounding context.

python
class GCloudOAuthProvider:
    """LLM provider that authenticates with Google Cloud Application Default Credentials.

    Obtains a fresh OAuth2 access token via ``google-auth`` on every call so
    tokens are never stale.  Set up credentials on the host with::

        gcloud auth application-default login

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · modules/btc_sprint_executor.py (reported line 5)May include surrounding context.

python
def build_reasoning(signal, regime, trade_amount: float, llm_reasoning: str | None = None) -> str:
    regime_bits = ', '.join(regime['warnings']) if regime['warnings'] else 'no warnings'
    base_reasoning = llm_reasoning or signal.reasoning
    return (
        f"{base_reasoning} Edge={signal.edge:.4f}, confidence={signal.confidence:.4f}, "

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares no explicit tool scope even though its documented and inferred capabilities include environment access, file reads/writes, and network use. In an agent setting, missing permission boundaries increases the blast radius of any prompt-injection, logic bug, or hidden behavior because the runtime may grant broader access than users expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

In live mode, the code calls auto_redeem() unconditionally at the start of each cycle, without any user-facing confirmation or separate enablement control. Even if redemption is intended housekeeping, it performs real account-affecting actions automatically, which is risky in a financial automation context because users may not expect balance-moving operations outside explicit trade placement.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

When no real BTC fast markets are available, the code fabricates a synthetic market, synthetic context, and synthetic signal, then routes that candidate through the normal selection and LLM decision path. In a trading skill, introducing non-real execution candidates undermines the trust boundary that decisions are based only on live market data and can cause misleading dry-run results, corrupted learning data, or accidental progression of fake inputs into code paths meant for real trades.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This module adds an outbound Discord notification capability that is not reflected in the stated BTC-only trading description, creating hidden external communication behavior. Undisclosed network egress increases security and privacy risk because trade activity, operational state, or future changes to message content could be transmitted off-platform without users expecting it.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code reads a webhook credential from environment variables and sends data to an external Discord endpoint, which is a real data egress capability beyond core trading logic. Even though the webhook URL is validated to Discord domains, this still enables exfiltration of sensitive operational information to a third-party service if messages include account, strategy, or execution details.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function performs outbound webhook delivery with no user-facing disclosure or runtime warning, which can mislead operators about the skill's external communications. While the behavior is not inherently malicious, lack of transparency makes unexpected data sharing more likely and reduces informed consent in automated trading environments.

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 · modules/btc_llm_decider.py (reported line 28)May include surrounding context.

python
DEFAULT_GOOGLE_MODEL = 'gemini-2.5-flash'
DEFAULT_DEEPSEEK_MODEL = 'deepseek-chat'
DEFAULT_CODEX_MODEL = 'codex-mini-latest'
DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1'
DEFAULT_OPENROUTER_BASE_URL = 'https://openrouter.ai/api/v1'
DEFAULT_GOOGLE_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta/openai/'
DEFAULT_DEEPSEEK_BASE_URL = 'https://api.deepseek.com'

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The hardcoded path to ~/.codex/auth.json indicates the module is designed to read a host user's local OAuth material. That is sensitive host state unrelated to BTC trade logic itself and can expose or normalize access to broader workstation credentials. In a skill expected to make trade decisions, coupling behavior to home-directory secrets increases the blast radius of compromise or misuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The code sends trading context to external LLM providers and later stores raw model output/payload in decision records, but this file contains no user-facing consent, minimization, or disclosure controls. While not inherently malicious, transmitting operational data and persisting model responses can leak strategy details, market positions, or other sensitive context to third parties and local logs. In a trading system, those disclosures can have business and privacy impact.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The Codex provider resolves tokens from environment variables and a host-local auth file under the user's home directory. Reading host-level credentials from a trading skill expands its privilege boundary beyond core decision logic and creates unnecessary access to unrelated secrets if the module is run on a developer or operator machine. In an adversarial skill-review context, host credential access is a meaningful risk even if the immediate use is API authentication.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module allows the LLM to suggest changes to live trading parameters, persists those suggestions, and automatically applies them after minimal counts-based thresholds. This creates an autonomous self-modifying control loop where an external model can indirectly change bankroll/risk behavior without robust human approval, bounded ranges, or provenance checks. In a live trading skill, that is materially dangerous because prompt injection, model error, or provider compromise could degrade safeguards and increase loss exposure.

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 · modules/btc_sprint_signal.py (reported line 11)May include surrounding context.

python
from urllib.request import urlopen


BINANCE_URL = "https://api.binance.us/api/v3/klines"


@dataclass

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest describes a strict BTC-only decision layer, but this module allows arbitrary symbols to be requested through the public fetch_binance_klines function and propagates that flexibility into build_signal. Because the code defaults to BTCUSDT but does not restrict callers to BTC, the implemented behavior is broader than the stated BTC-only scope.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest says the skill trades BTC 5m/15m fast markets, but build_signal accepts any interval string and fetches Binance klines for that interval. Although the window parameter influences 5m-vs-other logic, the actual market-data interval is not constrained to 5m or 15m semantics, so the code can operate outside the declared timeframe scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The code reads sensitive authentication material from Application Default Credentials, environment variables, and a local auth file in ~/.codex/auth.json. While this is functionally expected for provider authentication, the file does not include a clear warning or user-facing notice that local credentials will be accessed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This module writes JSON and JSONL records to disk, including learned parameters and pending rule state, through write_json_file() and callers such as record_pending_rule() and apply_eligible_rules(). There is no user-facing warning, print/log statement, or descriptive comment indicating that persistent local state will be modified.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · modules/btc_position_manager.py (reported line 9)May include surrounding context.

python
def _safe_get(obj, name, default=None):
    if isinstance(obj, dict):
        return obj.get(name, default)
    return getattr(obj, name, default)


def active_positions_for_skill(positions, skill_slug: str) -> list:

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code fetches market data from an external Binance API using an HTTP request, which transmits runtime parameters such as symbol, interval, and limit off-system. There is no confirmation prompt, user-facing log, or inline warning indicating that the skill makes outbound network calls.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.