T09 · Insecure Skill Coding Practices
- 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: HighVulnerable 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
- An attacker obtains the Skill package or accesses its source history.
- The attacker extracts the database endpoint, username, and plaintext password from
SKILL.md. - If the database is network-accessible and the credentials remain valid, the attacker connects directly to the MySQL endpoint.
- The attacker enumerates the data available to that account and reads any tables permitted by its effective grants.
- Independently, an agent may copy the documented block into a generated portfolio-analysis script.
- If a user ...[truncated 903 chars]
- Remediation
View remediation
Remediation Suggestions
- Immediately revoke and rotate the exposed password, even if it is believed to be obsolete.
- Review authentication logs for connections made with the exposed account.
- Remove the IP address, username, and password from the current file, repository history, release archives, logs, and cached artifacts.
- 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", )- Store production credentials in an approved secret manager rather than source files or documentation.
- Restrict the database firewall to approved source networks and require encrypted MySQL connections with certificate validation.
- Verify that the analysis account has only the minimum required
SELECTpermissions on the necessary table and cannot enumerate unrelated databases. - Use a dedicated credential for this Skill, prohibit password reuse, and rotate it regularly.
- Replace documentation examples with unmistakable placeholders and add automated secret scanning to the development and release pipeline.
