Back to skill

Security audit

数值计算器

Security checks for vulnerabilities and agentic risk

Overview

This calculator skill requires a remote API key, stores it in a local .env file, and sends calculations to an external service, which is disproportionate for basic arithmetic.

Review this skill carefully before installing. Only use it if you are comfortable providing a XiaoBenYang API key, storing it in a plaintext .env file, and sending calculation inputs to the remote service. Prefer a local calculator skill for basic arithmetic, or use a dedicated low-privilege API key and remove or rotate it after use.

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
scripts/config.py:45
Finding

Plaintext API Key Persistence and Configurable Credential Destination

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:18-25, 45-63, 70-78; scripts/call_api.py:49-78; SKILL.md:13-20, 32-38
Vulnerability Type: Plaintext secret storage and insufficient validation of a credential-bearing endpoint
Risk Level: Medium

Vulnerable Code

scripts/config.py:18-25:

python
# API配置
base_url: str = "https://mcp.xiaobenyang.com"
mcp_id: str = "1820705335657482"
api_key: str = ""

# 超时和重试配置
timeout_seconds: float = 30.0
max_retries: int = 2

scripts/config.py:45-63:

python
def save_api_key_to_env(api_key: str) -> bool:
    """将API key保存到.env文件"""
    try:
        env_path = Path(".env")
        lines = []
        if env_path.exists():
            lines = env_path.read_text(encoding="utf-8").splitlines()
        found = False
        new_lines = []
        for line in lines:
            if line.startswith("XBY_APIKEY="):
                new_lines.append(f"XBY_APIKEY={api_key}")
                found = True
            else:
                new_lines.append(line)
        if not found:
            new_lines.append(f"XBY_APIKEY={api_key}")
        env_path.write_text("\n".join(new_lines) + "\n", encoding="utf-8")
        os.environ["XBY_APIKEY"] = api_key
        return True

scripts/config.py:70-78:

python
def set_api_key(api_key: str) -> bool:
    """设置API key并持久化到.env"""
    if not api_key or not api_key.strip():
        return False
    api_key = api_key.strip()
    if not save_api_key_to_env(api_key):
        return False
    # 更新全局 settings 实例
    settings.api_key = api_key

scripts/call_api.py:49-78:

python
def call_tool(
    self,
    mcp_id: str,
    tool_name: str,
    params: dict[str, Any],
) -> HttpResult:
    """调用小笨羊MCP工具"""
    url = f"{settings.base_url}/api"
    mcp_id = mcp_id or settings.mcp_id

    api_key = get_api_key()
    if not api_key:

...[truncated 4062 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not persist API keys by default. Keep the key in memory for the current session or retrieve it from an operating-system credential store or managed secret service.
  2. If file persistence is explicitly approved, place the secret in a dedicated configuration directory and create the file atomically with owner-only permissions, such as mode 0600 on POSIX systems.
  3. Warn users before persistent storage and document the exact storage location, retention behavior, and deletion procedure.
  4. Prevent the secret file from entering source control by supplying an appropriate .gitignore rule, while recognizing that this does not replace filesystem access controls.
  5. Make the production API origin immutable where practical. Otherwise, validate it before attaching credentials:
    • Require the https scheme.
    • Require an exact approved hostname.
    • Reject embedded credentials, unexpected ports, and unapproved redirects.
  6. Disable redirects for credential-bearing requests or revalidate every redirect destination before forwarding sensitive headers.
  7. Do not mount or support plaintext HTTP for authenticated production requests.
  8. Separate endpoint configuration from credential handling so an untrusted environment variable cannot choose where a sensitive header is sent.
  9. Consider implementing elementary calculator operations locally, eliminating the need to transmit operands or require a remote API credential.
  10. Rotate any API key that may already have been stored in a broadly accessible .env file or sent while the endpoint configuration was untrusted.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (39)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A basic numeric calculator has no legitimate need to read and modify .env files, persist API keys, or manage remote-service configuration. These extra capabilities expand the attack surface and create credential-handling risks that are disproportionate to the advertised function.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

A basic numeric calculator has no legitimate need to read and modify .env files, persist API keys, or manage remote-service configuration. These extra capabilities expand the attack surface and create credential-handling risks that are disproportionate to the advertised function.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The description promises only basic math, but the workflow actually includes external API access, key storage, and returning raw remote data. This discrepancy undermines informed consent and can cause users to disclose credentials or data under false assumptions about the skill's behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill text explicitly says a numeric calculator must obtain and store an API key before use, which contradicts the expected local-only nature of calculator operations. In context, this makes credential collection suspicious and creates unnecessary exposure of user secrets to an external service.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

References to a different project name and an unrelated tool like search_schools strongly suggest copied or repurposed instructions inconsistent with the claimed calculator purpose. Such inconsistencies are dangerous because they indicate the skill may route inputs to unrelated external functionality or mask broader behavior than users expect.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code establishes outbound network access and posts arbitrary parameters to a remote endpoint, which is unnecessary for a simple calculator unless explicitly documented and tightly scoped. In the context of a calculator skill, this hidden remote-call capability is more dangerous because it expands the trust boundary, enables unexpected data exfiltration, and may proxy access to non-calculator functions.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill is described as a numeric calculator, but this file implements a generic remote MCP API invoker that can call arbitrary upstream tools by varying mcp_id, tool_name, and params. That creates a capability/description mismatch: users or higher-level agents may believe they are performing local arithmetic while their inputs are actually sent to an external service with broader execution scope.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

Configuring the application to load secrets from a repository-local .env file introduces credential-handling behavior into a calculator skill that should not need it. This expands exposure of secrets through local files and signals undeclared privileged capability inconsistent with the skill's stated purpose.

Content

Scanner excerpt · scripts/config.py (reported line 13)May include surrounding context.

python
model_config = SettingsConfigDict(
        env_prefix="XBY_GAOKAO_",
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
    )

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This calculator skill contains configuration for an external service, including a hard-coded service identifier and API credential handling, which is unrelated to the stated numeric-calculator purpose. In a narrowly scoped skill, unexpected remote-service integration and secret management materially increase the attack surface and create risk of covert data exfiltration or unauthorized outbound access.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code explicitly reads API keys from a local .env file and environment variable, then exposes helper functions to persist and retrieve them, despite the skill being presented as only a numeric calculator. Secret collection and persistence are dangerous here because they are unnecessary for the declared functionality and could be repurposed to harvest or retain credentials without clear need.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The post-init method forcefully reads XBY_APIKEY from .env, bypassing normal scoped configuration expectations and directly parsing local secret files. In the context of a simple calculator, this is particularly concerning because it adds deliberate credential-access logic unrelated to the advertised feature set.

Content

Scanner excerpt · scripts/config.py (reported line 31)May include surrounding context.

python
default_year: int = 2025

    def model_post_init(self, __context):
        # 强制从 .env 文件读取 XBY_APIKEY
        env_path = Path(".env")
        if env_path.exists():
            content = env_path.read_text(encoding="utf-8")

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The explicit existence check and read of the .env file are part of custom credential-access logic aimed at extracting API key material from local storage. This is dangerous because it normalizes direct secret harvesting behavior inside a skill whose declared scope does not require credentials.

Content

Scanner excerpt · scripts/config.py (reported line 32)May include surrounding context.

python
def model_post_init(self, __context):
        # 强制从 .env 文件读取 XBY_APIKEY
        env_path = Path(".env")
        if env_path.exists():
            content = env_path.read_text(encoding="utf-8")
            for line in content.splitlines():

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

This logic gives precedence to an environment variable for the same API key, further reinforcing credential collection and handling within the skill. Although reading environment variables is common in some applications, here it is misaligned with the declared calculator purpose and broadens the set of credential sources the skill can consume.

Content

Scanner excerpt · scripts/config.py (reported line 39)May include surrounding context.

python
if line.startswith("XBY_APIKEY="):
                    self.api_key = line.split("=", 1)[1].strip()
                    break
        # 如果环境变量有值,覆盖 .env 的值
        env_val = os.getenv("XBY_APIKEY", "")
        if env_val:
            self.api_key = env_val

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

This function is dedicated to saving API keys into a .env file, creating a persistent credential store managed by the skill itself. In a numeric calculator, such credential persistence is unnecessary and materially increases the risk of secret leakage through filesystem access, backups, or accidental inclusion in version control.

Content

Scanner excerpt · scripts/config.py (reported line 48)May include surrounding context.

python
def save_api_key_to_env(api_key: str) -> bool:
    """将API key保存到.env文件"""
    try:
        env_path = Path(".env")
        lines = []
        if env_path.exists():
            lines = env_path.read_text(encoding="utf-8").splitlines()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares itself as a simple calculator but omits any explicit tool-scope restrictions while documentation indicates access to environment variables, file read/write, and network. In a skill that also requests and persists an API key, missing scope boundaries increases the chance of unnecessary privileged actions or abuse if the implementation is broader than advertised.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Collecting and saving an API key for a calculator is unnecessary for the claimed task and increases the risk of credential compromise, especially when persistence behavior is mandated without clear safeguards. The mismatch between purpose and requested secret makes the request more suspicious in context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs the model to ask for and store an API key but does not warn users about persistence, where the credential will be stored, retention, or who can access it. That creates avoidable secret-handling risk and reduces informed user consent.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Directly displaying raw external API responses is unnecessary for calculator output and may expose implementation details, metadata, or unintended data returned by the remote service. In a misdescribed skill that already performs external calls, this increases data-leakage and prompt-surface risks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

params are serialized and transmitted directly to an external API without any evidence in this file of disclosure, minimization, or sanitization. In a calculator skill, users would reasonably expect local processing, so sending raw inputs off-box can expose sensitive data if users enter secrets, proprietary values, or prompt-derived content.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The class docstring identifies a different skill ('高考Skill配置') than the declared numerical calculator, which indicates code reuse or mismatch between implementation and manifest. Such inconsistencies are suspicious in security review because they can conceal undeclared capabilities and reduce operator trust in the skill's true behavior.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This function writes arbitrary API key material into a local .env file, adding persistence capability beyond what a calculator requires. Local secret persistence increases the risk of accidental disclosure through source-control commits, local file compromise, backups, or reuse by unrelated processes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code persists an API key to .env without any user-facing notice, confirmation, or explanation of the storage implications. Silent credential persistence is unsafe because users may not expect secrets to be written to disk, and it can lead to unintended long-term exposure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

该“数值计算器”并未在本地执行基础数学运算,而是把所有输入发送给外部 API。对于仅需本地算术的工具,这会无必要地扩大信任边界并引入数据外传、远端篡改结果、服务不可用或后端行为与声明不一致等风险。

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

对声明为“数值计算器”的技能来说,外部 API 调用属于与预期功能不相称的能力,说明其实际行为超出用户通常理解的本地计算范围。这样的能力错配会降低可审计性,并为隐蔽遥测、策略绕过或未来扩展为更高风险远程操作提供落点。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

文件中可见多个网络 API 调用,但没有任何面向用户的警示或披露,用户可能在不知情的情况下把输入发送到外部服务。即便输入看似只是数字,这种不透明的数据流仍违反最小惊讶原则,并可能掩盖更广泛的远程处理或日志记录。

Content

No source excerpt is available for this finding.