Back to skill

Security audit

US Stock Financials

Security checks for vulnerabilities and agentic risk

Overview

This SEC financial reporting skill is mostly purpose-aligned, but it automatically falls back to unverified HTTPS for financial data and recommends an unsafe system-level dependency install.

Review before installing or using for decisions: the skill can produce useful SEC financial reports, but its automatic insecure HTTPS fallback means financial figures could be spoofed on an intercepted network. Install dependencies in a virtual environment with pinned packages, and prefer a version that removes the TLS bypass before relying on generated reports.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sec_finance.py:104
Finding

Automatic fallback to unverified HTTPS connections

Content
View full analysis
ssl.SSLContext: ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE return ctx def _get_json(url: str, timeout: int = 20, retries: int = 2) -> dict: parsed = urllib.parse.urlparse(url) last_error = None for attempt in range(retries + 1): req = urllib.request.Request( url, headers={ "User-Agent": USER_AGENT, "Accept": "application/json", "Host": parsed.netloc, }, ) for ctx_factory in (_secure_ctx, _fallback_insecure_ctx): try: with urllib.request.urlopen(req, timeout=timeout, context=ctx_factory()) as resp: return json.loads(resp.read()) except ssl.SSLError as e: last_error = e continue except urllib.error.HTTPError as e: if e.code == 429 and attempt < retries: time.sleep(3 * (attempt + 1)) last_error = e break if e.code == 404: raise ValueError(f"CIK or resource not found: {url}") from e raise ValueError(f"HTTP {e.code} fetching {url}: {e.reason}") from e except urllib.error.URLError as e: last_error = e continue if attempt < retries: time.sleep(1.5 ** attempt) raise ConnectionError(f"Network/SSL error fetching {url}: {last_error}") def _get_text(url: str, timeout: int = 20) -> str: req = urllib.request.Request(url, headers={"User-Agent": USER_AGENT}) last_error = None for ctx_factory in (_secure_ctx, _fallback_insecure_ctx): tr ...[truncated 2762 chars]
Remediation
View remediation
ssl.SSLContext: return ssl.create_default_context() ``` 3. Replace both context loops with a single verified request: ```python with urllib.request.urlopen( req, timeout=timeout, context=_secure_ctx(), ) as resp: return json.loads(resp.read()) ``` 4. Treat certificate failures as terminal security errors and report them clearly rather than retrying insecurely. 5. If the runtime requires a private or custom certificate authority, explicitly load a controlled CA bundle: ```python ctx = ssl.create_default_context(cafile="/path/to/trusted-ca-bundle.pem") ``` 6. Do not disable hostname verification or use `ssl.CERT_NONE` in production. 7. Add automated tests confirming that self-signed, expired, untrusted, and hostname-mismatched certificates are rejected. 8. Consider enforcing an allowlist for remote hostnames so future changes cannot redirect requests away from the intended SEC domains. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:65
Finding

Unpinned dependency installation into a system-managed Python environment

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (7)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The network helpers intentionally retry requests with an SSL context that disables hostname verification and certificate validation. This makes HTTPS connections vulnerable to man-in-the-middle interception or tampering, allowing an attacker on the network path to supply forged SEC/EDGAR responses that the script will trust and parse.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill advertises commands that perform network access to SEC EDGAR and file output for PDF generation, but the manifest does not declare any explicit tool scope or permissions. This weakens least-privilege controls and makes it harder for a host system or reviewer to understand and constrain what the skill is allowed to do before execution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The file’s operational description, usage guidance, parameter explanations, and dependency notes are presented in Chinese, which effectively forces a specific language for users reading the skill. The policy allows locale constraints only when users are given a choice or the restriction is clearly documented and justified, neither of which is present here.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest contains very short and overloaded aliases such as "lu", "li", "ke", "api", "cd", "wb", and "trip" that are likely to collide with ordinary user text, other tickers, or unrelated terms. If alias resolution uses loose matching, an attacker or accidental prompt phrasing could cause the skill to select the wrong issuer and fetch or present incorrect financial data, which is especially risky in a finance-oriented skill where users may rely on precision.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code file contains natural-language descriptions and labels primarily in Chinese, including the module docstring and later user-facing table labels. The skill does not offer any language selection or indicate that Chinese output is optional, which creates a locale/language policy issue under the stated rule.

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/sec_finance.py (reported line 32)May include surrounding context.

python
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 "
    "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
)
XBRL_BASE = "https://data.sec.gov/api/xbrl"
EDGAR_BASE = "https://www.sec.gov/cgi-bin/browse-edgar"
ISSUERS_FILE = Path(__file__).resolve().parent.parent / "references" / "issuers.json"

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

User-visible strings such as metric labels, section titles, and status messages are emitted in Chinese, but the tool provides no CLI flag or configuration to opt into that locale. Because the file is not documented as a China-specific skill, this is a natural-language policy concern rather than a functional bug.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.