Back to skill

Security audit

极鲸云Ozon店铺搜索

Security checks for vulnerabilities and agentic risk

Overview

This Ozon research skill mostly matches its stated purpose, but it handles and stores GeekBI login tokens in broader local locations than the skill clearly discloses.

Install only if you are comfortable giving this skill access to a GeekBI login flow and having short-lived bearer tokens written to local JSON files. Prefer a version that stores credentials in one clearly named, user-specific secure store and documents how to revoke or clear the token.

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/geekbi_auth.py:69
Finding

Bearer Token Persisted in Plaintext Across Multiple Storage Locations

Content
View full analysis

Vulnerability Details

File Location: scripts/geekbi_auth.py:69-90, scripts/geekbi_auth.py:372-386, and scripts/geekbi_auth.py:637-652
Vulnerability Type: Plaintext credential storage and excessive credential replication
Risk Level: Medium

Vulnerable Code

python
def _user_config_state_path():
    return _absolute_path(
        user_config_path("GeekBI", appauthor=False, ensure_exists=True)
        / "temu-research-skill"
        / AUTH_FILE_NAME
    )


def _skill_state_path():
    return _absolute_path(Path(__file__).parent.parent / AUTH_STATE_DIR / AUTH_FILE_NAME)


def _workspace_state_path():
    return _absolute_path(Path(os.getcwd()) / AUTH_STATE_DIR / AUTH_FILE_NAME)


def _resolve_stores():
    candidates = (
        ResolvedStore(_user_config_state_path(), "user-config-directory"),
        ResolvedStore(_skill_state_path(), "skill-directory"),
        ResolvedStore(_workspace_state_path(), "working-directory"),
    )
python
def _write_state_files(stores, payload):
    normalized = _normalize_state(payload)
    errors = []
    written = 0
    for store in stores:
        try:
            _write_state_file(store, normalized)
            written += 1
        except OSError as error:
            errors.append(f"{store.kind}: {_storage_probe_reason(error)}")
python
def save_token(latest):
    latest_server = latest["servers"].get(server_key)
    if not isinstance(latest_server, dict):
        return False, False
    latest_pending = latest_server.get("pending")
    if not isinstance(latest_pending, dict):
        return False, False
    if latest_pending.get("deviceCode") != pending.get("deviceCode"):
        return False, False
    _remove_access_token(latest_server)
    latest_server["accessToken"] = access_token
    latest_server["accessTokenExpiresAt"] = now + max(0, expires_in - 30)
    latest_server.pop("pending",
...[truncated 3172 chars]
Remediation
View remediation

Remediation Suggestions

  1. Store authentication state in exactly one user-specific location. Remove the skill-directory and current-working-directory stores.
  2. Correct the namespace from temu-research-skill to a dedicated Ozon skill identifier to prevent cross-skill credential collisions.
  3. Use the operating system's credential manager, such as Keychain, Credential Manager, Secret Service, or a maintained keyring abstraction, rather than plaintext JSON.
  4. If file storage is unavoidable, encrypt the access token with a key held by the operating-system credential service.
  5. Treat inability to enforce restrictive permissions as a security failure rather than silently continuing. Verify ownership and permissions before reading or writing state.
  6. Avoid returning credential-store filesystem paths from routine status output unless explicitly requested for diagnostics.
  7. Migrate existing state by reading the highest-priority legacy file once, moving the credential into the new secure store, and securely deleting all legacy copies.
  8. Add tests confirming that authentication creates no state files in the project directory, installation directory, or arbitrary current working directory.
  9. Provide token revocation and comprehensive cleanup that removes all legacy replicas if credential exposure is suspected.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is ներկայացted as an Ozon shop search/analysis tool, but the detected behavior includes local persistence of authentication state, token management, auth-related network requests, and system-level file operations. That mismatch is dangerous because users and orchestrators may grant trust based on the declared business purpose while the skill can handle credentials and modify local state beyond that purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill is ներկայացted as an Ozon shop search/analysis tool, but the detected behavior includes local persistence of authentication state, token management, auth-related network requests, and system-level file operations. That mismatch is dangerous because users and orchestrators may grant trust based on the declared business purpose while the skill can handle credentials and modify local state beyond that purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is ներկայացted as an Ozon shop search/analysis tool, but the detected behavior includes local persistence of authentication state, token management, auth-related network requests, and system-level file operations. That mismatch is dangerous because users and orchestrators may grant trust based on the declared business purpose while the skill can handle credentials and modify local state beyond that purpose.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill declares no explicit tool scope or permission boundaries even though its referenced capabilities include file read, network, and shell access. This is dangerous because a user-facing data lookup skill can silently exercise broader privileges than its description implies, increasing the blast radius if the skill is misused, compromised, or incorrectly routed.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes a skill that queries and analyzes Ozon shop data based only on GeekBI-returned data, which implies a data retrieval/filtering capability. This file instead implements a broader authentication subsystem: persistent token storage, login state probing, clearing auth state, and browser-mediated action-required flows. While some auth is an implementation detail for network access, the extent of local state lifecycle management is materially broader than the manifest's stated analytical purpose.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This Python file contains user-facing natural-language strings in Chinese, beginning with the module docstring and continuing throughout errors and prompts. Because the file is code and provides no indication of locale opt-in or justification for a Chinese-only experience, it violates the language-choice policy.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest frames the skill as using GeekBI to query real Ozon shop data, but this module persists auth state across a user config directory, the skill directory, and the current working directory. That is a substantial local-storage behavior unrelated to the user-facing promise of shop search and analysis, and it is not disclosed by the manifest text.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The user-config path stores auth state under a different skill name ("temu-research-skill"), which can cause cross-skill state collision or unintended token reuse between unrelated skills. In this skill context, that is more dangerous because the module handles bearer-token login state, so a naming mix-up could lead to one skill reading, overwriting, or clearing another skill's authentication state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The clear_auth_state function unlinks stored authentication state files across multiple locations, which is a destructive operation affecting user data. The function performs the deletion silently and contains no confirmation prompt, warning log, or explanatory comment near the operation to disclose that auth state will be removed.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The text states that when no site is specified, the skill defaults to the Russian site (siteId=1). This is a natural-language locale policy concern because it imposes a specific regional setting automatically rather than offering user choice or explicit opt-in.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill's stated purpose is Ozon shop data lookup and analysis, but this file exposes operational capabilities for enumerating auth storage metadata and deleting auth state. Those are maintenance/admin functions rather than direct search or analysis features, and the manifest does not indicate such local state management tooling.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This Python skill performs an authenticated HTTP request to a remote API using user-supplied identifiers, which is a safety-relevant network operation under the rule. Although the script docstring says it queries Ozon store details, the code itself provides no explicit user-facing warning, confirmation, or comment near the transmission step explaining that the mall ID and site ID will be sent to an external service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The natural-language strings in the docstring, argument help, and error messages are exclusively in Chinese, which effectively constrains user interaction to a specific language. The file does not offer a language choice or indicate that the locale restriction is optional or justified as region-specific.

Content

No source excerpt is available for this finding.