Back to skill

Security audit

分类记忆服务

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to be a remote persistent-memory integration, but it needs Review because it stores an API key in plaintext, can send memory data to a configurable endpoint, and exposes broad delete operations without safeguards.

Review carefully before installing. Only use this if you trust the XiaoBenYang service and are comfortable sending memory contents to it. Use a limited API key, avoid storing sensitive secrets or private data as memories, check that .env is not committed or shared, and be cautious with delete-all or partial-match deletion commands.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:42
Finding

API Key Stored in a Plaintext File Without Permission Hardening

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py, lines 42-63
Vulnerability Type: Plaintext credential 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
    except Exception as e:
        print(f"保存API key失败: {e}")
        return False

Technical Analysis

The API key is written in plaintext to a predictable .env file in the current working directory. Path.write_text() neither applies an explicit restrictive permission mode nor verifies the file's owner. A newly created file therefore inherits permissions determined by the process umask, while an existing file retains its current permissions.

The project also provides no evidence that .env is excluded from source control, backups, artifact packaging, or access by other processes. Consequently, the credential may become available to local users or project-integrated tooling with read access.

Attack Path

  1. A user supplies an XBY_APIKEY as required by the Skill.
  2. set_api_key() calls save_api_key_to_env().
  3. The key is saved as plaintext in the working directory's .env file.
  4. Another local user, process, development tool, backup system, or accidentally published repository obtains the file.
  5. The exposed key is reused to authenticate to the XiaoBenYan ...[truncated 363 chars]
Remediation
View remediation

Remediation Suggestions

  • Prefer a platform secret manager, protected credential store, or session-only environment variable instead of persistent plaintext storage.
  • If file persistence is essential, create the file atomically with owner-only mode 0600.
  • Verify the file is a regular file owned by the expected user before reading or replacing it.
  • Avoid following symbolic links when creating or updating the credential file.
  • Store credentials in a fixed, access-controlled configuration directory rather than the process working directory.
  • Add .env to .gitignore and artifact exclusion rules.
  • Document credential rotation and immediately rotate any key believed to have been exposed.
  • Avoid placing the secret in multiple locations, such as both a file and mutable process environment, unless operationally necessary.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/call_api.py:47
Finding

Configurable API Endpoint Can Redirect Credentials and Memory Data

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py, lines 10-16; scripts/call_api.py, lines 47-75
Vulnerability Type: Unrestricted credential destination
Risk Level: High

Vulnerable Code

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

    base_url: str = "https://mcp.xiaobenyang.com"
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:
        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

Because Settings uses the XBY_GAOKAO_ environment prefix, the base_url setting can be overridden through XBY_GAOKAO_BASE_URL. The value is directly incorporated into the request URL without validating the scheme, hostname, port, or final destination.

The request includes both the plaintext API key in the custom XBY-APIKEY header and user-provided memory parameters in the body. Therefore, an attacker who can influence the process environment or configuration source can redirect these values to an attacker-controlled endpoint. No HTTPS-only requirement or trusted-host allowlist is enforced.

The requests client also follows redirects by default. The code does not explicitly prohibit cross-origin redirects or ensure that the custom credential header is removed before redirect processing ...[truncated 1237 chars]

Remediation
View remediation

Remediation Suggestions

  • Hard-code the production API origin when endpoint customization is unnecessary.
  • Otherwise, validate base_url against an explicit allowlist of approved HTTPS hostnames.
  • Reject non-HTTPS schemes, embedded user information, unexpected ports, fragments, and malformed URLs.
  • Disable automatic redirects for credential-bearing requests or validate every redirect destination before resending.
  • Never forward XBY-APIKEY across an origin change.
  • Separate endpoint configuration from untrusted environment or project-level .env files.
  • Apply deployment controls that prevent untrusted users from altering process environment variables.
  • Consider certificate pinning where the operational environment can support secure pin rotation.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unbounded Dependency Constraints Permit Unreviewed Package Releases

Content
View full analysis

Vulnerability Details

File Location: requirements.txt, lines 1-4
Vulnerability Type: Unpinned third-party dependencies
Risk Level: Medium

Vulnerable Code

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

Technical Analysis

Every dependency uses only a lower version bound. Package installation may consequently select any later release available from the configured package index. This makes installations non-reproducible and allows code that was not part of the audited dependency set to enter the runtime environment.

No lock file or cryptographic package hashes are present in the audited project. Although the named dependencies are not themselves demonstrated to be malicious, the dependency policy increases exposure to compromised future releases, package-index compromise, and unexpected compatibility or security regressions.

Attack Path

  1. The Skill is installed or rebuilt at a later date.
  2. The package resolver selects newer releases satisfying the open-ended constraints.
  3. A selected release contains compromised, malicious, or vulnerable code, or the configured package index is manipulated.
  4. The dependency is installed into the Skill environment.
  5. Its code executes during installation, import, or normal Skill operation with the privileges of the hosting process.

Impact Assessment

The potential impact depends on the behavior of a compromised dependency and the privileges of the installation or runtime process. It may include code execution, credential theft, memory-data disclosure, file modification, or network access. The audit found no evidence that the currently named packages are intentionally malicious; the confirmed issue is the absence of deterministic, integrity-verified dependency resolution.

Remediation
View remediation

Remediation Suggestions

  • Pin each direct and transitive dependency to a reviewed exact version.
  • Generate and commit a lock file appropriate for the deployment workflow.
  • Require cryptographic hashes during installation, for example through a hash-locked requirements file.
  • Install packages only from approved package indexes over authenticated TLS.
  • Run automated vulnerability and provenance checks during continuous integration.
  • Review dependency updates before merging and rebuild the lock file through a controlled process.
  • Periodically update pinned versions so security fixes are adopted without allowing uncontrolled upgrades.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (31)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The English-described purpose claims persistent classified memory, while the behavior instead centers on reading and writing an API key in .env, modifying environment state, and configuring an external service apparently tied to a different domain. This kind of deceptive or inconsistent documentation can conceal sensitive operations, mislead users into divulging credentials, and bypass meaningful review of what the skill actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The English-described purpose claims persistent classified memory, while the behavior instead centers on reading and writing an API key in .env, modifying environment state, and configuring an external service apparently tied to a different domain. This kind of deceptive or inconsistent documentation can conceal sensitive operations, mislead users into divulging credentials, and bypass meaningful review of what the skill actually does.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The workflow claims to implement a memory service, yet references unrelated school-search/API-calling behavior and generic routing to scripts.tools. In context, this inconsistency makes the skill more dangerous because it suggests copy-pasted or repurposed instructions that can mask real behavior and reduce reviewer confidence that data flows and external calls are understood or controlled.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file implements a general-purpose outbound API client that can invoke remote MCP tools, which materially exceeds the stated purpose of a classified persistent memory service. This expands the trust boundary from local memory handling to arbitrary remote capability execution, creating a hidden channel for data exfiltration, unexpected side effects, or remote action through a skill that users would reasonably expect to only store and retrieve memory.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The call_tool method accepts caller-controlled mcp_id, tool_name, and params and forwards them directly to an external API via headers and JSON body, effectively exposing arbitrary upstream tool invocation. In the context of a memory skill, this is especially dangerous because it can be used as a confused-deputy primitive to trigger unintended remote actions or send sensitive conversation-derived data to an external service unrelated to the declared functionality.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This module implements credential management and remote service configuration for an external '高考' service, which materially conflicts with the declared purpose of a '分类记忆服务'. Capability/purpose mismatch is dangerous because it can hide unrelated data exfiltration or third-party dependency behavior behind an innocuous skill label, reducing user scrutiny and review quality.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The class docstring identifies the code as configuration for a different skill ('小笨羊高考Skill配置'), directly contradicting the package metadata. Such identity mismatch is a strong indicator of copy-paste reuse or concealed functionality, both of which undermine auditability and can mask unauthorized behavior.

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

This code explicitly reads a local .env file and forcibly extracts XBY_APIKEY outside the standard settings flow. In a skill whose stated purpose is persistent memory, this undisclosed secret-reading behavior is more dangerous because it expands access to local credentials beyond user expectations and can facilitate misuse of those credentials.

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 construction and use of Path('.env') indicates deliberate access to a local secret-bearing file. In context, this is not just configuration plumbing; it is a direct file-read of a common credential container by a skill that does not appear to require such access for its advertised purpose.

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 is dedicated to writing an API key into a plaintext .env file, creating persistent local secret material. In the context of a mislabeled memory skill, this is especially concerning because it both manages credentials unrelated to the declared feature set and increases the chance of credential exposure through filesystem access or source-control mistakes.

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()

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

This deletion wrapper explicitly supports '*' to remove all categories, creating a highly destructive operation with no visible safeguard, confirmation mechanism, or scope restriction in the client code. In a memory service, accidental or induced invocation could wipe broad sets of persistent data, making the skill context materially more dangerous because the whole purpose is long-lived storage across sessions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill exposes capabilities consistent with environment access, file read/write, and network use, but does not declare any tool scope or permission boundaries. In a skill that also instructs the model to collect and persist an API key, this lack of explicit least-privilege controls increases the risk of overbroad access, unintended secret handling, and unreviewed external communication.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill requires the model to ask the user for an external API key and persist it, but that capability is not justified by the manifest’s stated purpose of simple categorized memory storage. Requesting and storing secrets under a misleading pretext is especially risky because it can trick users into disclosing credentials and creates long-lived secret exposure in .env or environment state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documented tools include destructive deletion operations, including wildcard removal of all categories, without prominent user-facing warnings or confirmation requirements. In a persistent memory context this is dangerous because an accidental or ambiguous prompt could trigger irreversible data loss across local or global memory scopes.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The project structure labels the package as a gaokao skill and emphasizes generic API client/configuration components rather than memory storage primitives, contradicting the claimed functionality. While this may stem from careless reuse, it materially increases supply-chain and social-engineering risk because users cannot reliably infer what data is collected, where it is sent, or why secret management is needed.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The configuration docstring is written as a Chinese-specific skill label, indicating a fixed locale context without any visible opt-in or language choice in this file. Under the policy, forcing a specific language or locale without user choice can be a natural-language policy violation unless the regional constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

A memory service should not unexpectedly introduce endpoint and credential configuration for an unrelated external service. In this context, that expands the trust boundary and creates an undisclosed channel through which user data or operational context could be sent off-box.

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 to a local .env file without any user-facing disclosure, consent flow, permission checks, or file-permission hardening. Storing secrets in plaintext can expose credentials to other local users, accidental commits, backups, logs, or later compromise of the workspace.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The function sends user-provided data, category, and tags to call_api, which is a network/API transmission of potentially sensitive memory content. While the docstring says the function stores memory, this file provides no explicit user-facing warning, confirmation, or disclosure about transmitting that data to an external API.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Deleting memories by partial content match is dangerous because ambiguous input can remove unintended records, especially in a persistent cross-session memory store where similar entries are likely. The absence of an exact identifier or confirmation step raises the risk of overbroad deletion and data integrity loss.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency is specified with a lower bound only, so installs may resolve to different versions over time, including versions later found to be vulnerable or behaviorally incompatible. In a persistent-memory service that likely handles user data and network access, lack of version pinning weakens supply-chain reproducibility and makes security posture unverifiable.

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 pin requests, so it is impossible to determine whether deployed environments may resolve to a version affected by known advisories. For a memory service likely making HTTP calls, requests is a security-sensitive library and version ambiguity can expose credential leakage, TLS, or request-handling issues depending on the resolved release.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Using pydantic with only a minimum version allows uncontrolled resolution to any newer release, which can introduce vulnerable or breaking versions into deployments. Because this skill is a persistence-related service, validation logic is security-relevant, so unpinned versions reduce confidence that input handling remains safe and consistent.

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