Back to skill

Security audit

MBTI测试服务

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches an MBTI testing service, but it stores an API key in plaintext and contains mismatched gaokao configuration that users should review before installing.

Install only if you trust the XiaoBenYang API service and are comfortable storing its API key in a local .env file. Review or fix the gaokao naming/configuration mismatch, restrict the API endpoint, avoid committing .env, and consider using a secret store or owner-only file permissions before 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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:45
Finding

API Key Persisted in a Plaintext File Without Restrictive Permissions

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py, lines 45-62
Vulnerability Type: Plaintext sensitive-data storage
Risk Level: Medium

Vulnerable Code

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

Technical Analysis

The user-supplied API key is written directly to a .env file in plaintext. The implementation does not create the file with owner-only permissions, verify the permissions of an existing file, reject symbolic links, or use an operating-system credential store.

A newly created file inherits permissions determined by the process umask. An existing file retains its current permissions. Consequently, the secret may be readable by other local principals or processes with access to the working directory. Writing through a predictable relative path also creates a potential symlink-based disclosure or overwrite concern when the working directory is not trusted.

Attack Path

  1. A user supplies an API key as required by the Skill.
  2. set_api_key() invokes save_api_key_to_env().
  3. The function stores the key as XBY_APIKEY=<secret> in the working directory's .env file.
  4. Another local user or process reads a permissively accessible file, or the file is accidentally committ ...[truncated 456 chars]
Remediation
View remediation

Remediation Suggestions

  • Prefer obtaining the key from a process environment variable or operating-system secret store without persisting it in the project directory.
  • If file persistence is required, create the file atomically with owner-only mode 0600.
  • Verify and correct permissions when updating an existing file.
  • Reject symbolic links and other non-regular files before reading or writing the path.
  • Store secrets in a user-specific configuration directory rather than the current working directory.
  • Ensure .env is excluded from version control, build artifacts, diagnostics, and backups.
  • Document credential rotation and revocation procedures.
  • Avoid retaining the secret in process state longer than required.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:9
Finding

Configurable API Endpoint Can Redirect Credentials and MBTI Session Data

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py, lines 9-16; credential transmission occurs in scripts/call_api.py, lines 51-76
Vulnerability Type: Unvalidated credential destination
Risk Level: Medium

Vulnerable Code

python
class Settings(BaseSettings):
    """小笨羊高考Skill配置"""
    
    model_config = SettingsConfigDict(
        env_prefix="XBY_GAOKAO_",
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
    )

    # API配置
    base_url: str = "https://mcp.xiaobenyang.com"

The configurable value is subsequently used as the credential-bearing destination:

python
url = f"{settings.base_url}/api"
mcp_id = mcp_id or settings.mcp_id

api_key = get_api_key()
if not api_key:
    raise UpstreamError("API密钥未设置,请先调用 set_api_key()")

headers = {
    "XBY-APIKEY": api_key,
    "func": tool_name,
    "mcpid": mcp_id,
    "Content-Type": "application/json",
}

t0 = time.time()
try:
    resp = self._session.post(
        url=url,
        headers=headers,
        data=json.dumps(params),
        timeout=settings.timeout_seconds,
    )

Technical Analysis

Pydantic settings permit base_url to be overridden through the XBY_GAOKAO_BASE_URL environment variable or the .env settings source. The client sends the API key, selected tool name, MCP identifier, and request parameters to that configured endpoint without validating its scheme or hostname.

Therefore, a party capable of influencing the process environment or .env configuration can redirect credential-bearing requests to an attacker-controlled server. The affected parameters include MBTI test type, answers, and full session state.

This issue requires prior ability to influence local configuration; it is not independently remotely exploitable from ordinary MBTI answers.

Attack Path

  1. An attacker or compromised deployment mechanism modifies ...[truncated 874 chars]
Remediation
View remediation

Remediation Suggestions

  • Hard-code the production API origin or validate it against an explicit allowlist such as https://mcp.xiaobenyang.com.
  • Require HTTPS and reject URLs containing unexpected hosts, ports, user-information components, query strings, or fragments.
  • Resolve and normalize the URL before validation.
  • Do not attach API credentials to requests after a cross-origin redirect; preferably disable redirects for credential-bearing calls.
  • Separate test endpoint support from production credential handling and require explicit development-mode configuration.
  • Treat .env and deployment environment variables as security-sensitive configuration with restricted write access.
  • Add tests confirming that non-HTTPS and non-allowlisted destinations are rejected before any request is sent.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (31)

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.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This second mismatch is stronger because the skill explicitly instructs the agent to obtain and persist an API key into a local .env file, while project naming and configuration references point to a different 'gaokao' service. That combination suggests copy-pasted or repurposed infrastructure that could redirect user credentials to an unrelated external service, violating user expectations and increasing secret-handling risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This second mismatch is stronger because the skill explicitly instructs the agent to obtain and persist an API key into a local .env file, while project naming and configuration references point to a different 'gaokao' service. That combination suggests copy-pasted or repurposed infrastructure that could redirect user credentials to an unrelated external service, violating user expectations and increasing secret-handling risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The configuration clearly targets a different service domain ('高考' / gaokao) than the declared MBTI testing skill, including a mismatched environment prefix and external API metadata. This creates a serious supply-chain and trust-boundary issue: the skill may send user data or credentials to an unrelated backend, violating least surprise and potentially exposing sensitive interactions to the wrong service.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

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",
    )

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

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

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

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

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

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
60% confidence
Finding

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

Content

Scanner excerpt · scripts/config.py (reported line 39)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")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill declares no explicit tool scope or permission boundaries despite documented capabilities to read/write local files, access environment variables, and call external networks. In an agent setting, missing scope restrictions increases the blast radius if the skill is misrouted, modified, or abused, especially because it also persists secrets to local storage.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the agent to solicit an API key from the user and save it, but provides no warning about where it will be stored, who can access it, or what service it belongs to. This is dangerous in context because the skill already shows signs of purpose mismatch and local secret persistence, so users may unknowingly disclose credentials to an unrelated or weakly controlled integration.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The workflow and tool examples reference gaokao/school-search behavior rather than MBTI testing, showing the skill instructions are internally inconsistent. In practice, such inconsistencies can cause an agent to invoke unintended tools or send user inputs to the wrong backend, which is especially risky when credentials and network access are involved.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This file implements a generic upstream MCP proxy via call_tool(mcp_id, tool_name, params) instead of restricting behavior to MBTI-specific operations. In the context of an MBTI testing skill, exposing arbitrary tool selection and arbitrary parameter forwarding materially expands capability scope, enabling the skill to invoke unrelated upstream functions if an attacker can influence tool_name, mcp_id, or params.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The method constructs headers using caller-influenced tool_name and mcp_id and forwards arbitrary params directly to the upstream API, effectively giving this skill general proxy capability. Because the skill's declared purpose is MBTI testing, this mismatch increases the risk of unauthorized actions, privilege expansion, or hidden functionality unrelated to the advertised service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code performs an HTTP POST to an external service and includes both an API credential in headers and arbitrary request parameters in the body. While logging exists for success and error cases, there is no user-facing confirmation, warning, or explanatory comment/docstring disclosing that user-supplied data and credentials will be sent off-system.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The inline docstring describes a different skill ('高考Skill配置') than the manifest-declared MBTI service, which is a concrete indicator of code provenance mismatch. While not directly exploitable by itself, this kind of misleading labeling can conceal unsafe backend reuse, cause reviewers to miss inappropriate data flows, and undermine user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code persists the API key to a local .env file automatically, without any explicit user confirmation, permission check, or storage hardening. If the working directory is shared, backed up, committed, or readable by other local users/processes, the credential can be exposed and reused to access the external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The function transmits the user's answer score together with the full session object to an external API, potentially exposing more behavioral/profile data than necessary. In a personality-testing context, this creates a privacy risk because response patterns and session state can reveal sensitive inferred traits, and the code provides no evidence of minimization, redaction, or user disclosure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The instruction to directly show raw API return data, combined with the statement that the code 'only calls the API,' reveals that this skill behaves like an API proxy rather than a bounded MBTI assistant. Returning raw upstream data can leak implementation details, identifiers, or unexpected content to users and reduces opportunities for validation or output filtering.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The project structure still references a 'gaokao' skill, which undermines trust in the declared MBTI purpose and supports the broader evidence of repurposed infrastructure. While not independently severe, this inconsistency increases the likelihood of accidental misconfiguration, wrong endpoint usage, or credential reuse against an unintended service.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified with a lower bound only, so builds may resolve to different versions over time. This weakens reproducibility and can unintentionally introduce vulnerable or incompatible releases into the deployment supply chain.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
89% confidence
Finding

The manifest does not identify the exact requests version that will be installed, so it is impossible to verify whether known advisories affect this deployment. In an AI-facing service that may make outbound HTTP calls, an unverified HTTP client dependency increases uncertainty around credential handling and request security.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The pydantic dependency is unpinned, which allows future installs to pull any newer version meeting the minimum constraint. This creates supply-chain risk because a newly published vulnerable or breaking version could be installed without code changes.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1

Unverifiable Dependency: pydantic has 4 known advisory(ies) (CVE-2021-29510 (Use of "infinity" as an input to datetime and date fields causes infinite loop i); CVE-2024-3772 (Pydantic regular expression denial of service); CVE-2021-29510 (Pydantic is a data validation and settings management using Python type hinting.) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
87% confidence
Finding

Because pydantic is not pinned, the project cannot demonstrate that installed versions are outside known vulnerable ranges. Since this package often processes untrusted input, unresolved advisory exposure can affect validation or parsing safety.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

Using only a minimum version for pydantic-settings means dependency resolution is not deterministic. Non-reproducible dependency selection increases the chance of silently consuming a vulnerable upstream release.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1