Back to skill

Security audit

LBS Market Analyzer

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed AMAP market-analysis tool, but it also provisions account API keys and persists credentials and browser login state in ways users should review before installing.

Install only if you are comfortable letting the skill open an AMAP browser session, create an AMAP application and Web Service key, and store that key locally. Treat .env and ./amap_session as sensitive, keep them out of source control and shared folders, rotate any exposed key, and prefer manually providing AMAP_KEY or using a secure secret store instead of running the automator.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/amap_key_automator.py:135
Finding

AMAP API Key Disclosed Through Console Output

Content
View full analysis

Vulnerability Details

File Location: scripts/amap_key_automator.py, line 135
Vulnerability Type: Plaintext secret disclosure through application logs
Risk Level: Medium

Vulnerable Code

python
try:
    # Locate the key by finding the row with our key name
    row_locator = page.locator("tr", has=page.locator("text='lbs-ca-key'")).first
    # The key is in the second td of that row
    key_value = await row_locator.locator("td").nth(1).inner_text()
    key_value = key_value.strip()

    print(f"Success: Extracted AMAP Key: {key_value}")

    # Save to .env (Project Root)
    script_dir = os.path.dirname(os.path.abspath(__file__))
    project_root = os.path.dirname(script_dir)
    env_path = os.path.join(project_root, ".env")
    with open(env_path, "a", encoding="utf-8") as f:
        f.write(f"\nAMAP_KEY={key_value}\n")

Technical Analysis

The provisioning script prints the complete newly created AMAP API key to standard output. Standard output is frequently retained by terminal recorders, agent execution histories, CI/CD systems, centralized logging platforms, and process supervisors.

The key is a bearer-style credential used by competitor_analysis.py to authenticate requests to the AMAP API. Any party able to read retained output can reuse it without access to the original AMAP account. Printing the credential is not required for the declared functionality because the script already writes it to the configured credential file.

Attack Path

  1. A user runs scripts/amap_key_automator.py and completes AMAP authentication.
  2. The script creates and extracts a Web Service API key.
  3. Line 135 writes the complete key to standard output.
  4. An agent transcript, terminal logger, CI runner, or centralized logging service retains the output.
  5. A party with access to those logs retrieves the key.
  6. The party submits authenticated requests to AMAP using the exposed crede ...[truncated 447 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove the statement that prints the complete key.
  • If confirmation is necessary, print only a redacted fingerprint, such as the final four characters:
    python
    print(f"Success: AMAP key created: ****{key_value[-4:]}")
    
  • Configure execution environments to redact common secret patterns from logs.
  • Avoid returning the key in exceptions, status objects, or agent messages.
  • Rotate any API key that may already have appeared in retained logs.
  • Review and purge accessible historical logs containing the plaintext credential.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/amap_key_automator.py:11
Finding

Persistent Authenticated Browser Profile Stored in a Predictable Local Directory

Content
View full analysis

Vulnerability Details

File Location: scripts/amap_key_automator.py, lines 6 and 11-14
Vulnerability Type: Insecure persistence of authenticated browser state
Risk Level: High

Vulnerable Code

python
# Configuration
USER_DATA_DIR = "./amap_session"  # Directory to save login state
AMAP_CONSOLE_URL = "https://console.amap.com/dev/key/app"

async def automate_amap_key():
    async with async_playwright() as p:
        # Launch browser with persistent context to keep you logged in
        context = await p.chromium.launch_persistent_context(
            user_data_dir=USER_DATA_DIR,
            headless=False,
            args=["--start-maximized"]
        )

Technical Analysis

Playwright's persistent browser context stores cookies, local storage, session state, and other browser-profile data on disk. The script deliberately retains this profile in the relative and predictable ./amap_session directory so that authentication survives subsequent runs.

No restrictive directory permissions, profile encryption, lifetime limit, cleanup operation, or logout procedure is implemented. Because the path is relative to the current working directory rather than a controlled private location, the profile may also be created in an unintended shared directory.

Retaining browser authentication is not required after an API key has been provisioned. It therefore exceeds the minimum persistence needed for the core market-analysis function and increases the consequences of local directory exposure.

Attack Path

  1. The user starts the automator and logs in to the AMAP console.
  2. AMAP authentication cookies and related state are written under ./amap_session.
  3. The script closes the browser but does not delete or invalidate the persisted session.
  4. Another local user, process, backup service, artifact collector, or accidental repository commit obtains the profile directory.
  5. The exposed p ...[truncated 814 chars]
Remediation
View remediation

Remediation Suggestions

  • Prefer an ephemeral Playwright context and require interactive authentication only during provisioning.
  • Delete the browser profile immediately after extracting the key unless the user explicitly opts into session retention.
  • If persistence is necessary, store the profile in a user-private operating-system data directory rather than a relative project path.
  • Create the profile directory with owner-only permissions, such as mode 0700 on supported systems.
  • Add amap_session/ to .gitignore and exclude it from backups, build artifacts, and agent uploads.
  • Provide an explicit cleanup command that deletes the profile and directs the user to revoke active AMAP sessions.
  • Document the retained authentication state and obtain user consent before creating it.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/amap_key_automator.py:140
Finding

AMAP API Key Stored in a Plaintext Environment File Without Permission Hardening

Content
View full analysis

Vulnerability Details

File Location: scripts/amap_key_automator.py, lines 140-143
Vulnerability Type: Insecure plaintext credential storage
Risk Level: Medium

Vulnerable Code

python
script_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(script_dir)
env_path = os.path.join(project_root, ".env")
with open(env_path, "a", encoding="utf-8") as f:
    f.write(f"\nAMAP_KEY={key_value}\n")

Technical Analysis

The API key is appended directly to a plaintext .env file. The script does not explicitly enforce owner-only permissions, verify whether the destination is a symbolic link, prevent duplicate key entries, or confirm that the project directory is private.

The file is opened in append mode, so repeated provisioning can retain obsolete credentials alongside the current key. The reviewed project also contains no .gitignore entry demonstrating that .env and the browser-profile directory are excluded from source control.

A local environment file may be appropriate for development, but securely storing the credential requires restrictive permissions and protection against accidental publication. The current implementation makes the credential available to every user or process that can read the project file.

Attack Path

  1. The provisioning script obtains an AMAP API key.
  2. The key is appended in plaintext to the project-root .env file.
  3. The project directory is read by another local process or user, synchronized to backup storage, packaged as an artifact, or committed to source control.
  4. The plaintext key is recovered from .env.
  5. The exposed key is used to make AMAP requests until it is revoked or expires.

If an attacker can pre-create .env as a symbolic link and the process runs with greater file privileges, the append operation could also target another writable file. The practical effect depends on local filesystem permissions and th ...[truncated 434 chars]

Remediation
View remediation

Remediation Suggestions

  • Prefer an operating-system credential manager or dedicated secrets service over a plaintext project file.
  • If .env storage is retained, create the file atomically with owner-only permissions, such as mode 0600 on supported systems.
  • Resolve and validate the destination path, reject symbolic links, and ensure the parent directory is trusted.
  • Replace an existing AMAP_KEY entry instead of appending duplicate credentials.
  • Add .env to .gitignore and exclude it from packages, backups, diagnostics, and uploaded artifacts.
  • Warn users that the file contains a live credential and provide a secure key-rotation procedure.
  • Revoke and replace keys that may already have been committed or otherwise exposed.
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
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill description claims market-intelligence analysis features, but the documented behavior includes browser automation for AMAP account/app/key management and local credential persistence to .env, which are materially different and more sensitive actions. This mismatch can mislead users and reviewers into authorizing a skill for benign analytics while it performs credential-handling and account-management operations with higher security risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description claims market-intelligence analysis features, but the documented behavior includes browser automation for AMAP account/app/key management and local credential persistence to .env, which are materially different and more sensitive actions. This mismatch can mislead users and reviewers into authorizing a skill for benign analytics while it performs credential-handling and account-management operations with higher security risk.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The script handles a live API credential and then stores it in a local .env file, which is a credential access and persistence behavior. In the context of an analysis skill, automatic extraction and storage of a secret is especially sensitive because it turns the tool into a credential-provisioning mechanism that could leak or misuse account resources.

Content

Scanner excerpt · scripts/amap_key_automator.py (reported line 132)May include surrounding context.

python
print(f"Success: Extracted AMAP Key: {key_value}")
            
            # Save to .env (Project Root)
            script_dir = os.path.dirname(os.path.abspath(__file__))
            project_root = os.path.dirname(script_dir)
            env_path = os.path.join(project_root, ".env")

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

Appending AMAP_KEY directly into .env persists a valid secret in plaintext on disk. Plaintext credential storage in a project root is dangerous because it may be readable by other local processes, included in backups, or accidentally committed to source control, resulting in credential compromise and unauthorized API use.

Content

Scanner excerpt · scripts/amap_key_automator.py (reported line 135)May include surrounding context.

python
# Save to .env (Project Root)
            script_dir = os.path.dirname(os.path.abspath(__file__))
            project_root = os.path.dirname(script_dir)
            env_path = os.path.join(project_root, ".env")
            with open(env_path, "a", encoding="utf-8") as f:
                f.write(f"\nAMAP_KEY={key_value}\n")
            print(f"Saved key to {env_path}")

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/competitor_analysis.py (reported line 83)May include surrounding context.

python
parser.add_argument("--radius", type=int, default=3000)
    args = parser.parse_args()

    # Load variables from .env file
    # Get the directory of the current script, then go up one level to the project root
    script_dir = os.path.dirname(os.path.abspath(__file__))
    project_root = os.path.dirname(script_dir)

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/competitor_analysis.py (reported line 87)May include surrounding context.

python
# Get the directory of the current script, then go up one level to the project root
    script_dir = os.path.dirname(os.path.abspath(__file__))
    project_root = os.path.dirname(script_dir)
    dotenv_path = os.path.join(project_root, ".env")
    load_dotenv(dotenv_path)

    key = os.getenv("AMAP_KEY")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises executable workflows that access environment variables, write to local files, and make networked/API requests, yet it declares no explicit tool scope or permissions boundary. In an agent ecosystem, this weakens reviewability and can allow the skill to exercise sensitive capabilities without clear user or platform consent, especially because it also instructs writing credentials into .env.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The instructions prescribe specific Chinese search terms for residential, commercial, and traffic anchors, which imposes a language/locale assumption in the skill content. The file does not offer an alternative language choice or explain that the analysis is limited to a Chinese-language or China-specific dataset/context.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill’s stated purpose is market analysis, but this script performs browser automation to create AMAP developer applications and provision API keys. That is a privileged side effect beyond pure analysis, expands the attack surface into account operations, and could cause unauthorized account changes or key sprawl if run in an agent context without explicit user understanding.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
81% confidence
Finding

Using timeout=0 on page navigation allows the browser automation to wait indefinitely on an external site. In an unattended agent environment, this can hang execution, consume resources, and create a denial-of-service condition for the workflow or host process.

Content

Scanner excerpt · scripts/amap_key_automator.py (reported line 21)May include surrounding context.

python
page = await context.new_page()
        print(f"Navigating to {AMAP_CONSOLE_URL}...")
        try:
            # timeout=0 means wait indefinitely
            await page.goto(AMAP_CONSOLE_URL, wait_until="domcontentloaded", timeout=0)
        except Exception as e:
            print(f"Navigation warning: {e}")

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · scripts/amap_key_automator.py (reported line 22)May include surrounding context.

python
print(f"Navigating to {AMAP_CONSOLE_URL}...")
        try:
            # timeout=0 means wait indefinitely
            await page.goto(AMAP_CONSOLE_URL, wait_until="domcontentloaded", timeout=0)
        except Exception as e:
            print(f"Navigation warning: {e}")

Context Window Stuffing

Medium
Category
Memory Poisoning
Confidence
85% confidence
Finding

Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Content

Scanner excerpt · scripts/amap_key_automator.py (reported line 77)May include surrounding context.

python
await input_locator.fill("lbs-ca", timeout=5000)
            print("Successfully filled application name.")
        except Exception as e:
            print(f"Failed to find or fill the input field: {e}")

        # Select an industry type (often required, id="industryId")
        try:

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script extracts a newly created AMAP API key and appends it directly to the project’s .env file, creating and storing credentials as a side effect. This is dangerous because credentials may be written into insecure locations, accidentally committed to source control, or exposed to other tools and users sharing the workspace.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code writes the extracted API key to the project .env file without warning, review, or consent from the user. Silent credential persistence is risky because users may not realize a secret was created and stored locally, increasing the chance of accidental disclosure or policy violations.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency 'playwright' is unpinned, so installs may resolve to different versions over time, including versions with newly introduced vulnerabilities, breaking changes, or supply-chain compromise risk. In a skill that uses browser automation, this increases exposure because Playwright executes complex browser-facing code and often processes untrusted web content.

Content

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

text
playwright
python-dotenv

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency 'python-dotenv' is unpinned, which makes builds non-reproducible and can silently introduce vulnerable or incompatible releases. Because this skill advertises automated API key provisioning and likely handles secrets through environment files, an unsafe dependency update in dotenv handling is especially relevant to confidentiality and integrity of local files and secrets.

Content

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

text
playwright
python-dotenv

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), 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 includes 'python-dotenv' without a version pin, and the package has known advisories; therefore it is impossible to verify from this file whether the installed version is affected. In this skill's context, dotenv is likely used for API key provisioning and secret management, so a vulnerable release could enable unsafe .env handling such as file overwrite or unintended secret exposure pathways.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring says this is a script for the 'geo-competitor-insight' skill, while the provided manifest context is for 'lbs-market-analyzer'. That inline documentation contradicts the stated skill identity/context rather than merely omitting details.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.