Back to skill

Security audit

Private Fund Portfolio Analysis

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent private-fund portfolio analysis helper, but it includes hardcoded MySQL connection defaults that could expose or unintentionally use database credentials.

Review this before installing. The portfolio-analysis behavior is understandable, but the published skill should remove the hardcoded MySQL defaults and rotate any exposed credential. Use only authorized, least-privilege database access, provide secrets through protected environment variables or a secrets manager, and treat generated CSV/JSON/PNG reports as sensitive financial files.

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

Error
Location
SKILL.md:85
Finding

Hardcoded MySQL Endpoint and Credentials

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 85–92
Vulnerability Type: Hardcoded plaintext credentials and external database configuration
Risk Level: High

Vulnerable Code

python
conn = pymysql.connect(
    host=os.environ.get("MYSQL_HOST", "43.138.222.153"),
    port=int(os.environ.get("MYSQL_PORT", "3306")),
    user=os.environ.get("MYSQL_USER", "readonly_user"),
    password=os.environ.get("MYSQL_PASSWORD", "w6w%vkXENC82PGZo"),
    database=os.environ.get("MYSQL_DATABASE", "指数行情数据库"),
    connect_timeout=8, charset="utf8mb4"
)

Technical Analysis

The Skill documentation embeds a public database IP address, username, and plaintext password as fallback values. Because os.environ.get() returns these defaults whenever the corresponding environment variables are absent, code copied or generated from this example can automatically connect to the fixed external database.

Embedding secrets in a distributed Skill exposes them to every person or system that can read the package, its archives, logs, or source-control history. Environment-variable overrides do not protect the embedded values. The configuration also conflicts with the Skill's own instruction not to hardcode real passwords or addresses.

The account is named readonly_user, but its actual database grants cannot be established from the reviewed files. Therefore, read-only access must not be assumed without verification.

Attack Path

  1. An attacker obtains the Skill package or accesses its source history.
  2. The attacker extracts the database endpoint, username, and plaintext password from SKILL.md.
  3. If the database is network-accessible and the credentials remain valid, the attacker connects directly to the MySQL endpoint.
  4. The attacker enumerates the data available to that account and reads any tables permitted by its effective grants.
  5. Independently, an agent may copy the documented block into a generated portfolio-analysis script.
  6. If a user ...[truncated 903 chars]
Remediation
View remediation

Remediation Suggestions

  1. Immediately revoke and rotate the exposed password, even if it is believed to be obsolete.
  2. Review authentication logs for connections made with the exposed account.
  3. Remove the IP address, username, and password from the current file, repository history, release archives, logs, and cached artifacts.
  4. Require explicit configuration and fail closed when mandatory values are missing:
python
required = ["MYSQL_HOST", "MYSQL_USER", "MYSQL_PASSWORD", "MYSQL_DATABASE"]
missing = [name for name in required if not os.environ.get(name)]
if missing:
    raise RuntimeError("Missing required database configuration: " + ", ".join(missing))

conn = pymysql.connect(
    host=os.environ["MYSQL_HOST"],
    port=int(os.environ.get("MYSQL_PORT", "3306")),
    user=os.environ["MYSQL_USER"],
    password=os.environ["MYSQL_PASSWORD"],
    database=os.environ["MYSQL_DATABASE"],
    connect_timeout=8,
    charset="utf8mb4",
)
  1. Store production credentials in an approved secret manager rather than source files or documentation.
  2. Restrict the database firewall to approved source networks and require encrypted MySQL connections with certificate validation.
  3. Verify that the analysis account has only the minimum required SELECT permissions on the necessary table and cannot enumerate unrelated databases.
  4. Use a dedicated credential for this Skill, prohibit password reuse, and rotate it regularly.
  5. Replace documentation examples with unmistakable placeholders and add automated secret scanning to the development and release pipeline.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill embeds a real-looking MySQL host, username, password, and database name as default connection parameters. Even if labeled as a placeholder, hardcoded secret-like defaults in documentation or sample code can lead to credential leakage, unintended access to external infrastructure, and propagation of sensitive values into generated scripts or logs.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The description says the skill triggers not only for private-fund valuation-table portfolio analysis, but also for broad tasks like generating scripts, refactoring scripts, adding new data sources, fixing script bugs, and generating analysis reports. These phrases do not clearly distinguish when this skill should activate versus other general coding or reporting skills, increasing the risk of unintended invocation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill instructs use of external data sources and database access, and writes output files, but does not warn about privacy, data handling, or local file side effects. In the context of private fund holdings analysis, this increases the risk of exposing sensitive portfolio data to external services, querying production infrastructure unintentionally, or writing sensitive reports to insecure locations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

SQP-3 applies to all file types and covers natural-language locale policy violations. This script embeds user-facing instructions entirely in Chinese, including the generated prompt content, and does not provide an opt-in or alternative language, which can force a specific language on users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
69% confidence
Finding

The skill content is entirely presented in Chinese and uses Chinese benchmark names and instructions, but it does not state that the skill is China-specific or offer any language/locale choice. This can constitute a language or locale policy issue when users are not given an explicit opt-in or justification for the enforced locale.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file documents use of MYSQL_PASSWORD as a required environment variable, which involves sensitive credential handling. The section provides setup instructions but does not include any warning about protecting secrets, avoiding shell history exposure, or using secure secret management.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The note states that utf8mb4 must be used because Chinese industry names otherwise fail, which imposes a locale-specific assumption in the skill documentation. There is no indication that this is optional, user-selected, or scoped to a region-specific dataset.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.