Back to skill

Security audit

stock-rumors-aisa

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but its script can send the AISA API key to an arbitrary endpoint if the runtime environment sets an undocumented override.

Install only if you trust the runtime environment and the AISA credential is scoped and revocable. Do not run it with AISA_BASE_URL set unless you intentionally trust that endpoint; rotating the key is prudent if it was used with an unexpected endpoint.

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/rumor_scanner.py:143
Finding
Environment-Controlled API Endpoint Can Disclose the AISA API Key## Vulnerability Details **File Location**: `scripts/rumor_scanner.py`, lines 143–150 and 164–170 **Vulnerability Type**: Unrestricted authenticated API destination override **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 sends an authenticated request here: ```python try: response = client.chat.completions.create( model=model, messages=[ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": prompt}, ], temperature=0.2, ) ``` ### Technical Analysis The Skill legitimately requires `AISA_API_KEY` to authenticate with its declared AISA service. However, `get_client()` also reads the undocumented `AISA_BASE_URL` environment variable and accepts its value without validating the scheme, hostname, port, or trust relationship. The `OpenAI` client is initialized with both the legitimate API key and this unrestricted destination. Consequently, a process launcher, compromised parent process, poisoned execution environment, or surrounding automation capable of setting `AISA_BASE_URL` can redirect the authenticated completion request to an attacker-controlled server. Sending the key to the default AISA endpoint is necessary for the declared functionality. Allowing an arbitrary destination is not required for rumor scanning and expands the Skill's trust boundary beyond minimum privilege. ### Attack Path 1. An attacker gains influence over the environment used to launch the Skill, such a ...[truncated 1512 chars]
Remediation
## Remediation Suggestions 1. Remove the `AISA_BASE_URL` override and use the declared service directly if alternate endpoints are not essential: ```python AISA_BASE_URL = "https://api.aisa.one/v1" return OpenAI(api_key=api_key, base_url=AISA_BASE_URL) ``` 2. If endpoint customization is a required feature, parse the URL and enforce an explicit allowlist: - Require HTTPS. - Permit only approved AISA hostnames. - Reject embedded user information. - Reject unapproved ports. - Reject malformed URLs and IP-literal bypasses. - Normalize and validate the hostname before comparison. 3. Prevent credentials from being forwarded across redirects to a different origin. Configure the HTTP client to reject cross-origin redirects for authenticated requests or disable redirects entirely. 4. Document any supported endpoint override in `SKILL.md`, including the security implications. Require explicit user confirmation before sending credentials to any non-default approved host. 5. Use a narrowly scoped, revocable API key with spending and quota limits. Rotate the key immediately if it may have been used while `AISA_BASE_URL` pointed to an untrusted destination. 6. Add automated tests verifying that non-HTTPS URLs, arbitrary domains, deceptive subdomains, user-info URLs, and unapproved ports are rejected before client initialization.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Credential Access

High
Category
Privilege Escalation
Content
## 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
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill declares access to a sensitive environment variable (AISA_API_KEY) but does not define an explicit tool scope such as permissions or allowed-tools. That creates unnecessary ambiguity about what runtime capabilities the skill is permitted to use, which weakens containment and reviewability even if the current markdown appears benign.

External Transmission

Medium
Category
Data Exfiltration
Content
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)
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Low
Confidence
89% confidence
Finding
The manifest sets `"language": "en"`, which is a natural-language locale constraint. Because this file provides no indication that the skill offers language choice or that English-only behavior is justified by a region-specific requirement, it may violate the language/locale policy criteria.

Static analysis

No suspicious patterns detected.