Back to skill

Security audit

FootyClaw: AI Quant Betting Agent

Security checks for vulnerabilities and agentic risk

Overview

FootyClaw is a coherent football betting assistant, but it needs review because it recommends wager amounts and tracks bankroll/shareholder ledger details without enough user safeguards.

Review before installing. Use only where sports betting is legal for you, treat recommendations as informational rather than reliable financial advice, set your own limits, and avoid storing sensitive personal finance details unless you are comfortable with the agent keeping them in session memory. Configure a narrowly scoped ODDS_API_KEY if possible and rotate it if it may appear in URL logs.

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

Note
Location
scripts/daily_scanner.py:33
Finding

API Credential Exposed in Query String by Daily Scanner

Content
View full analysis
`. 3. A server-side access log, proxy, monitoring service, or diagnostic mechanism records the full URL. 4. An attacker or unauthorized operator obtains read access to that record. 5. The attacker extracts the API key from the query string. 6. The attacker reuses the key with The Odds API until it is revoked, rotated, or its quota is exhausted. This path requires access to URL-bearing logs or diagnostics; the audited code does not ...[truncated 543 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/fetch_odds.py:18
Finding

API Credential Exposed in Query String by Odds Fetcher

Content
View full analysis
Remediation
View remediation
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (17)

Tainted flow: 'url' from os.environ.get (line 43, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/daily_scanner.py (reported line 45)May include surrounding context.

python
}
    url = f"{BASE_URL}/sports/{sport_key}/odds?" + urllib.parse.urlencode(params)
    try:
        with urllib.request.urlopen(url, timeout=15) as resp:
            remaining = resp.headers.get("x-requests-remaining", "?")
            print(f"  [{sport_key}] quota remaining: {remaining}", file=sys.stderr)
            return json.loads(resp.read().decode())

Tainted flow: 'url' from os.environ.get (line 27, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/fetch_odds.py (reported line 29)May include surrounding context.

python
}
    url = f"{BASE_URL}/sports/{sport_key}/odds?" + urllib.parse.urlencode(params)
    try:
        with urllib.request.urlopen(url, timeout=15) as resp:
            remaining = resp.headers.get("x-requests-remaining", "?")
            used = resp.headers.get("x-requests-used", "?")
            print(f"# API quota: {remaining} remaining / {used} used", file=sys.stderr)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
77% confidence
Finding

secrets 描述文本直接使用中文表述,且整份技能文档均默认中文交互,没有说明可根据用户偏好切换语言或提供语言选择。按规则,若技能强制特定语言而未提供用户选择或明确合理的地区性限定,属于自然语言层面的语言/locale 策略风险。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill describes end-to-end betting recommendations, bankroll sizing, shareholder tracking, and persistent session-memory bookkeeping without clear user risk disclosures. In this context, omission of warnings increases the chance users treat the output as safe financial advice and may disclose or persist sensitive financial information without informed consent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger list includes broad everyday phrases such as ‘查赔率’, ‘今天有什么场’, and ‘记账/更新账本’, which can unintentionally activate the skill in ordinary conversation. Because the skill performs gambling-related analysis, bankroll handling, and memory-backed ledger operations, accidental invocation can lead to inappropriate betting recommendations or unintended financial-state changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This content gives concrete betting instructions, confidence ratings, expected value framing, and stake sizing templates without any warning about financial loss, gambling harm, or legal/regulatory constraints. In the context of an agent skill, this can normalize risky wagering behavior and encourage users to act on financial advice-like recommendations without safeguards.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code file contains user-facing natural-language text in Chinese in the module docstring and later emits Chinese status/error/output strings. Under the policy rule for all file types, forcing a specific language without user opt-in is a locale-policy violation when no alternative or justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The argparse description, help text, stderr messages, and generated HTML alt text are presented only in Chinese. Because the script provides no language selection or explicit region-specific justification, this is a natural-language locale policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file hard-codes league names in Chinese and later prints Chinese-only status/output messages and a Beijing-time heading, which imposes a specific language/locale on all users. The policy allows locale constraints only when documented and justified or when the user can opt in, neither of which is present here.

Content

No source excerpt is available for this finding.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · scripts/daily_scanner.py (reported line 107)May include surrounding context.

python
print(f"\n📋 共 {len(all_games)} 场,开始EV分析...\n")

    # 通过 stdin 管道把 JSON 传给 ev_calculator,零文件写入
    ev_script = str(((__import__('pathlib')).Path(__file__).parent / "ev_calculator.py"))
    proc = subprocess.run(
        [sys.executable, ev_script, "--stdin",
         "--min-ev", str(args.min_ev),

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/daily_scanner.py (reported line 108)May include surrounding context.

python
# 通过 stdin 管道把 JSON 传给 ev_calculator,零文件写入
    ev_script = str(((__import__('pathlib')).Path(__file__).parent / "ev_calculator.py"))
    proc = subprocess.run(
        [sys.executable, ev_script, "--stdin",
         "--min-ev", str(args.min_ev),
         "--bankroll", str(args.bankroll)],

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This Python file contains multiple user-facing help and console messages exclusively in Chinese, such as the argparse help text and printed status/output lines. The skill does not offer a language/locale option or document that it is intentionally region-specific, which violates the policy against forcing a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring and later user-facing usage/output strings include Chinese-only text, which imposes a specific language on users without any opt-in or alternative. This matches the language/locale policy violation category because the script does not offer a language selection or document a justified locale restriction.

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 · scripts/daily_scanner.py (reported line 18)May include surrounding context.

python
from datetime import datetime, timezone

API_KEY = os.environ.get("ODDS_API_KEY", "")
BASE_URL = "https://api.the-odds-api.com/v4"

def fetch_odds(sport_key, regions="eu", markets="h2h,spreads,totals"):
    if not API_KEY:

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 · scripts/fetch_odds.py (reported line 14)May include surrounding context.

python
from datetime import datetime, timezone

API_KEY = os.environ.get("ODDS_API_KEY", "")
BASE_URL = "https://api.the-odds-api.com/v4"

def fetch_odds(sport_key, regions="eu", markets="h2h,spreads,totals"):
    if not API_KEY:

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

No manifest is available to justify the skill's intended scope, so capability should be inferred conservatively from the file's own stated purpose. A 'daily match scanner' fetching matches does implement remote access as documented, but reading an API key from the environment introduces credential access capability that is not itself described in the module documentation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

No manifest is available, so the skill has no declared purpose or scope to justify capabilities. The code explicitly reads ODDS_API_KEY from the environment, which is a credential-access capability beyond simple local formatting or display logic and is not grounded in any stated intent outside the module docstring.

Content

No source excerpt is available for this finding.