Back to skill

Security audit

stock-hot

Security checks for vulnerabilities and agentic risk

Overview

This market-scanning skill mostly matches its purpose, but it can send the user's AISA API key to an undocumented custom endpoint if the environment is changed.

Review before installing. Use only in an environment where AISA_API_KEY is narrowly scoped and where AISA_BASE_URL cannot be set by untrusted launchers, shell profiles, wrappers, or project files. Prefer a version that pins dependencies and either removes custom endpoint support or validates and documents trusted endpoints.

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/hot_scanner.py:111
Finding

API Credential Can Be Redirected to an Arbitrary Network Endpoint

Content
View full analysis

Vulnerability Details

File Location: scripts/hot_scanner.py, lines 111–116 and 146–154
Vulnerability Type: Unvalidated authentication endpoint configuration
Risk Level: High

Vulnerable Code

python
def get_client() -> OpenAI:
    api_key = os.environ.get("AISA_API_KEY")
    if not api_key:
        print("❌ Error: AISA_API_KEY environment variable is not set.", file=sys.stderr)
        print("   Set it with: export AISA_API_KEY=your_key_here", file=sys.stderr)
        sys.exit(1)
    base_url = os.environ.get("AISA_BASE_URL", "https://api.aisa.one/v1")
    return OpenAI(api_key=api_key, base_url=base_url)

The resulting client is later used to send an authenticated request:

python
response = client.chat.completions.create(
    model=model,
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": prompt},
    ],
    temperature=0.2,
)

Technical Analysis

The application reads the sensitive AISA_API_KEY credential from the environment but independently obtains the destination from the unrestricted AISA_BASE_URL environment variable. No URL scheme, hostname, port, or destination allowlist validation is performed.

The OpenAI-compatible client uses the configured API key to authenticate requests sent to the configured base URL. Consequently, a party capable of influencing the scanner's environment can set AISA_BASE_URL to an attacker-controlled service. When the scanner makes its completion request, the authentication credential can be exposed to that service.

Network access and transmission of the API key to the legitimate AISA API are necessary for the declared live market-scanning functionality. Allowing an arbitrary destination is not necessary for that functionality and exceeds least-privilege configuration requirements.

Attack Path

  1. An attacker gains the ability to influence the environment used t ...[truncated 1309 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove support for AISA_BASE_URL if custom endpoints are not essential and use a constant trusted endpoint:
    python
    base_url = "https://api.aisa.one/v1"
    
  2. If endpoint customization is required, validate the parsed URL against an explicit allowlist of trusted HTTPS hostnames.
  3. Reject plaintext HTTP, embedded URL credentials, unexpected ports, IP-address destinations, and URLs whose normalized hostname is not explicitly trusted.
  4. Do not reuse AISA_API_KEY with custom endpoints. Require a separate, clearly named credential for non-production or custom servers.
  5. Fail closed when endpoint validation fails and avoid including credential values in errors or logs.
  6. Document every supported endpoint override and warn that custom endpoints receive authentication material and request contents.
  7. Where supported, use narrowly scoped, revocable API credentials with usage limits and monitor for unexpected destinations or consumption.

T08 · Insecure Dependencies

Warning
Location
scripts/hot_scanner.py:2
Finding

Unpinned Third-Party Dependency Permits Unreviewed Future Package Releases

Content
View full analysis

Vulnerability Details

File Location: scripts/hot_scanner.py, lines 2–7
Vulnerability Type: Unbounded dependency resolution
Risk Level: Medium

Vulnerable Code

python
# /// script
# requires-python = ">=3.10"
# dependencies = [
#     "openai>=1.0.0",
# ]
# ///

Technical Analysis

The inline dependency declaration specifies only a minimum version for the openai package. It therefore permits any future package version satisfying >=1.0.0, rather than the exact version reviewed with this Skill.

A metadata-aware runner such as the uv run command referenced in the script documentation may resolve and install a newer release at execution time. Code imported from that package runs in the scanner process and can access its environment, including AISA_API_KEY, and perform network or filesystem operations with the process user's permissions.

This is a supply-chain hardening issue rather than evidence that the current openai package is malicious. Exploitation depends on a future compromised, malicious, or otherwise unsafe matching release being selected by the dependency resolver.

The project also documents inconsistent runtime paths: the script header refers to uv run, while SKILL.md identifies direct python3 execution as canonical. This can produce inconsistent dependency installation and version-selection behavior across environments.

Attack Path

  1. The Skill is invoked using a runner that processes the inline dependency metadata.
  2. The runner resolves the latest package version satisfying openai>=1.0.0.
  3. A compromised, malicious, or unreviewed future release is selected and installed.
  4. Python imports the package when executing from openai import OpenAI.
  5. Package code executes with the scanner process's permissions and can access AISA_API_KEY and other process-accessible resources.
  6. The package may exfiltrate credentials, alter requests, manipulate out ...[truncated 786 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin the dependency to an exact, reviewed version instead of using an unrestricted lower bound:
    python
    # dependencies = [
    #     "openai==<audited-version>",
    # ]
    
  2. Generate and commit a lockfile containing exact transitive dependency versions and integrity hashes.
  3. Configure installations to require hashes and use a trusted package index.
  4. Review dependency updates before changing the lockfile, including release notes, ownership changes, and vulnerability advisories.
  5. Use automated dependency scanning and alerting while avoiding automatic deployment of unreviewed major releases.
  6. Document one consistent installation and execution path so direct python3 and metadata-aware runner behavior do not diverge.
  7. Run the Skill with a restricted environment and filesystem permissions to reduce the impact of a compromised dependency.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 31)May include surrounding context.

md
## When NOT to Use

- Do not use this skill for browser-cookie extraction, passwords, Keychain access, or other local sensitive credential access.
- Prefer a different skill when the user request is outside this skill's domain.

## Capabilities

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares access to an environment variable containing an API key but does not define any explicit tool scope or permission boundary. This increases the risk of overbroad execution or unintended secret exposure because the runtime requirements are present without a corresponding restriction model in the manifest.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The description uses broad trigger language like 'what is hot' and 'what is moving,' which can match common conversational requests outside a clearly bounded finance context. Overbroad routing can cause the skill to activate unexpectedly, exposing credentials or invoking code paths when a more appropriate non-executing response would have been safer.

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

python
print("❌ Error: AISA_API_KEY environment variable is not set.", file=sys.stderr)
        print("   Set it with: export AISA_API_KEY=your_key_here", file=sys.stderr)
        sys.exit(1)
    base_url = os.environ.get("AISA_BASE_URL", "https://api.aisa.one/v1")
    return OpenAI(api_key=api_key, base_url=base_url)

Vague Triggers

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The usage guidance remains high-level and does not define sufficiently strict activation boundaries, so adjacent requests about trends or 'what's moving' could still invoke the skill too easily. In a tool-enabled environment, vague invocation criteria increase the chance of unnecessary execution and secret-bearing environment exposure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest sets "language": "en", which indicates an English-only locale choice in natural-language metadata. There is no accompanying opt-in, alternate locale support, or justification showing that this skill must be restricted to English for a region-specific or compliance reason.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.