Back to skill

Security audit

星座服务

Security checks for vulnerabilities and agentic risk

Overview

This zodiac skill appears to be an API wrapper, but it needs review because it saves an API key in plaintext and contains inconsistent gaokao/school-search leftovers.

Review before installing. Only use this skill if you are comfortable giving it a XiaoBenYang API key and having that key stored in a local plaintext .env file. Treat birth time and precise location entered for rising-sign calculations as data sent to an external service. The publisher should remove the gaokao leftovers, document exact data flows, and use secure credential storage before this is treated as routine.

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:47
Finding

API Key Persisted in Plaintext Without Enforced File Permissions

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:47-60
Vulnerability Type: Plaintext sensitive-data storage with unsafe inherited permissions
Risk Level: Medium

Vulnerable Code

python
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 application stores the user-supplied API key as plaintext in a .env file relative to the process's current working directory. The write operation does not explicitly create the file with restrictive permissions, verify file ownership, reject symbolic links, or correct unsafe permissions on an existing file.

The resulting permissions depend on the process umask and any permissions already assigned to .env. In an unsafe deployment environment, another local user or process may be able to read the credential. Writing through a predictable relative path also increases exposure to working-directory mistakes and symbolic-link attacks when an attacker can modify that directory.

Exploitation requires local access to the file or control over the directory in which the application runs. The code does not establish that the file is universally readable, so exposure is conditional on deployment permissions.

Attack Path

  1. A user supplies an API key as required by the Skill.
  2. set_api_key() passes the secret to save_api_key_to_env().
  3. The function writes the key as XBY_APIKEY=<secret> into .env in the current working directory.
  4. The file inherits permissions determined by the process umask or ...[truncated 836 chars]
Remediation
View remediation

Remediation Suggestions

  • Prefer an operating-system credential manager, secret-management service, or runtime environment variable instead of persistent plaintext storage.
  • If file persistence is unavoidable, use a dedicated per-user configuration directory rather than the current working directory.
  • Create the credential file atomically with owner-only permissions equivalent to 0600.
  • Verify that the destination is a regular file owned by the expected user, and reject symbolic links or unexpected ownership.
  • Check and correct the permissions of an existing .env file before writing credentials.
  • Write to a securely created temporary file, apply restrictive permissions, and atomically replace the destination to avoid partial writes and race conditions.
  • Document where the key is stored, which external service receives it, and how users can rotate or revoke it.
  • Ensure the .env file is excluded from version control, backups, diagnostic bundles, and application logs.
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented purpose says this is a zodiac service, but the content includes unrelated references to gaokao/school-search configuration and a different project identity, indicating the skill may not do what it claims. Description-behavior mismatch is dangerous because it can mislead users into authorizing a harmless-looking skill that actually performs secret collection, persistence, or unrelated network operations.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The configuration code is clearly mismatched to the advertised horoscope service and instead manages credentials and endpoints for an unrelated XBY/gaokao platform. In an agent skill context, such hidden cross-service credential handling is dangerous because it can exfiltrate, misuse, or confuse secrets and route requests to an unintended backend without the operator realizing it.

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

The code manually reads the .env file and forcefully extracts XBY_APIKEY outside the normal typed settings flow. In the context of a mismatched skill, this behavior is more suspicious because it bypasses clearer configuration patterns and directly targets a specific secret for another service.

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

The explicit file access to .env is part of a custom credential extraction path, which unnecessarily broadens secret-handling exposure. In an agent skill, direct parsing of secret files is riskier than delegated configuration loading because it makes undeclared secret access easier to hide and extend.

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

This function writes an API key into .env on disk, creating a durable local secret artifact that may be readable by other users, included in backups, or accidentally committed. In a repackaged or misleading skill, silent secret persistence is especially concerning because operators may not expect the skill to retain credentials for another platform.

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 no explicit tool scope or permission boundaries even though it is documented as using environment access, local file read/write, and networked API calls. In an agent setting, missing scope declarations increase the chance of overbroad execution and make it harder for users or the platform to understand that the skill can persist secrets and access external services.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

The skill metadata and entire user-facing instructions are written as a Chinese-only service, with no indication that users may choose another language or that the locale limitation is intentional and justified. This can constitute a language/locale policy issue when a skill implicitly forces a specific language without opt-in.

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 request and save an API key but does not tell users how the credential will be stored, how long it will persist, or what protections apply. Collecting secrets without transparent handling guidance can lead to accidental exposure, reuse beyond user expectations, or insecure persistence in local files such as .env.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The instructions explicitly require the agent to solicit a secret from the user and persist it for later reuse, without any minimization, masking, or least-retention safeguards. In agent environments, encouraging plain-language secret collection is risky because the secret may enter logs, transcripts, prompts, or local files outside a secure secret-management path.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The workflow repeats a mandatory pattern of collecting a user secret and storing it before any functionality can continue, normalizing insecure secret handling as part of routine operation. Repetition increases the likelihood that downstream implementations will persist credentials in unsafe locations or expose them in conversation history.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The example invocation and workflow documentation are inconsistent with the advertised zodiac theme and contain school-search content, suggesting copy-paste residue or deceptive packaging. Such inconsistencies reduce auditability and can conceal unintended tool usage or parameter flows from users and reviewers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code sends the caller-supplied params payload to settings.base_url via an outbound POST request. While the file contains internal logging for success and errors, it does not provide a user-facing warning, confirmation, or explanatory comment/docstring that data supplied in params will be transmitted off-system.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The docstring identifies the module as a different skill, which strongly suggests code reuse or repackaging inconsistent with the declared purpose. In security review, this matters because mismatched identity increases the chance that the skill is performing undeclared actions or relying on secrets for another system.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function persists an API key directly into a local .env file and updates process environment state without any user confirmation, warning, or secure storage controls. This increases the risk of accidental secret disclosure through source control inclusion, filesystem exposure, backups, or reuse by other components on the host.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The get_rising_sign function transmits sensitive personal data—full birth date, birth time, and precise location coordinates—to an external API via call_api, but this file shows no consent flow, minimization, or disclosure mechanism. In the context of an astrology skill, this data is not obviously dangerous by itself, but it is still personal profiling data that can create privacy risk if logged, retained, or shared by the downstream service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The rising-sign feature requires detailed birth date, time, and location data, which are sensitive personal attributes, but the skill provides no privacy warning or minimization guidance. Even if the data is used for a legitimate feature, collecting it without clear disclosure can expose users to unnecessary privacy risk.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The project directory name references a gaokao skill rather than a zodiac service, which reinforces that the package identity does not match its description. While this alone may be low severity, in combination with secret handling and network access it increases suspicion of repurposed or mislabeled code.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified with a lower bound only (requests>=2.31.0), which makes builds non-reproducible and can cause the environment to resolve to a vulnerable or incompatible future release. In a network-facing MCP service, using an unpinned HTTP client increases supply-chain risk because security posture depends on whatever version gets installed at deploy time.

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

The manifest does not pin requests, so it is impossible to verify from this file alone whether deployment will use a version affected by known advisories. In an MCP service that likely performs outbound HTTP requests, this uncertainty is security-relevant because vulnerable client behavior could affect credential handling, TLS verification, or request integrity depending on the resolved version.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

pydantic>=2.7.0 is unpinned, so installations may pull different versions over time, including versions later found vulnerable or behaviorally incompatible. Because this library is often used for parsing and validation, unexpected resolver drift can affect both security controls and runtime stability.

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

Because pydantic is unpinned, the actual installed version cannot be verified against known advisories from the manifest alone. This is dangerous insofar as validation libraries sit on trust boundaries, and a vulnerable version could enable denial of service or flawed input handling if resolved during installation.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

pydantic-settings>=2.2.0 is not pinned, which prevents reproducible builds and leaves the deployed version uncertain. Since settings libraries commonly process secrets and environment-derived configuration, version drift can expose the service to newly introduced vulnerabilities or unsafe defaults.

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

Unverifiable Dependency: pydantic-settings has 1 known advisory(ies) (CVE-2026-58203 (pydantic-settings: NestedSecretsSettingsSource follows symlinks outside secrets_)), 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

pydantic-settings is not version-pinned, so the dependency may resolve to a release with known security issues without that being visible in the manifest. Given its role in loading configuration and potentially secrets, uncertainty around the installed version creates avoidable risk even if no exploit path is proven from this file alone.

Content

No source excerpt is available for this finding.