Back to skill

Security audit

Shanghai Stock Exchange Composite Index - 上证股票指数

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed stock-index API skill that uses a JisuAPI key for its intended service, with a credential-handling weakness users should be aware of.

Install only if you are comfortable giving the skill a JisuAPI AppKey and allowing calls to JisuAPI. Avoid sharing transcripts or logs from failed runs, and rotate the key if error output ever contains the appkey value.

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

Warning
Location
stockindex.py:16
Finding
Potential API Credential Disclosure Through Raw Exception Output## Vulnerability Details **File Location**: `stockindex.py`, lines 16–25; output sink at line 83 **Vulnerability Type**: Sensitive credential exposure through verbose error handling **Risk Level**: Medium ### Technical Analysis The application places `JISU_API_KEY` in the HTTP query parameters and returns the unfiltered string representation of any exception raised by `requests.get()`. ```python def _call_api(path: str, appkey: str, params: dict = None): if params is None: params = {} all_params = {"appkey": appkey} all_params.update({k: v for k, v in params.items() if v not in (None, "")}) url = f"{BASE_URL}/{path}" try: resp = requests.get(url, params=all_params, timeout=10) except Exception as e: return {"error": "request_failed", "message": str(e)} ``` The returned error object is subsequently serialized to standard output: ```python print(json.dumps(result, ensure_ascii=False, indent=2)) ``` Because the API key is included in the prepared request URL, request-related exceptions may contain request details, including the URL or query string. Returning `str(e)` without sanitization creates a credential-disclosure channel. Output may then be retained in terminal history, application logs, agent transcripts, monitoring systems, or error collectors. The credential is transmitted to the intended service over HTTPS, so this finding does not allege plaintext network transmission. The weakness is specifically the possibility of exposing the credential through diagnostic output. ### Attack Path 1. A valid `JISU_API_KEY` is configured in the process environment. 2. The script constructs an HTTP request whose query string contains `appkey=<credential>`. 3. An attacker or an environmental failure causes a request exception that includes prepared-request information, such as through malformed proxy behavior, redirect failures, transport-layer errors, or ...[truncated 1283 chars]
Remediation
## Remediation Suggestions 1. Do not return raw exception strings to users or agent output. Replace them with a fixed message: ```python except requests.RequestException: return { "error": "request_failed", "message": "The stock-index service request failed." } ``` 2. Catch `requests.RequestException` rather than the broad `Exception` class. Unexpected programming errors should be handled separately and logged through a controlled internal mechanism. 3. If diagnostic logging is required, log only the exception class and a sanitized message. Remove query strings entirely or explicitly redact `appkey` before recording request information. 4. Prefer an authorization header instead of a query parameter if the upstream API supports it. If query authentication is mandatory, ensure URLs are never emitted to standard output, exception telemetry, access logs, or tracing systems. 5. Add automated tests that simulate request exceptions containing a URL with `appkey=secret-value` and verify that neither the returned object nor serialized output contains the secret. 6. Rotate the API key if existing logs or transcripts may already contain request exception output.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding
Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill declares that it requires an environment variable containing an API key and invokes a Python script that necessarily performs outbound network access, but the manifest does not define an explicit tool/permission scope such as allowed-tools or permissions. That creates an authorization gap: a host agent may grant broader execution or network behavior than users expect, reducing transparency and increasing the chance of unintended secret exposure or unauthorized external requests.

External Transmission

Medium
Category
Data Exfiltration
Content
import requests


BASE_URL = "https://api.jisuapi.com/stockindex"


def _call_api(path: str, appkey: str, params: dict = None):
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.