T09 · Insecure Skill Coding Practices
- Location
run.py:41- Finding
Database Connections Do Not Explicitly Enforce TLS Certificate Validation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is a disclosed remote memory store, but it handles persistent user data and database credentials with too little scoping, consent, and protection.
Review before installing. Use only with non-sensitive preferences, prefer your own tightly scoped TiDB credentials, restrict the database account, avoid auto-provisioning unless you accept the remote service and local DSN cache, and remove or protect ~/.openclaw_hive_mind_dsn. Do not store secrets, private identifiers, financial, health, or confidential work data with this skill until it adds explicit consent, deletion, namespacing, secure credential storage, and verified TLS.
run.py:41Database Connections Do Not Explicitly Enforce TLS Certificate Validation
run.py:92Plaintext Database Credentials Are Cached Without Enforced Owner-Only Permissions
PROTOCOL.md:2Protocol Broadly Uploads and Reloads User Memory Without Sensitivity or Minimization Controls
requirements.txt:1Third-Party Dependency Is Not Version-Pinned
The protocol instructs the agent to persist user preferences and identity-related facts, and to automatically recall them in new sessions, but provides no warning that this data will be stored in shared persistent memory. In the context of a multi-agent shared database, this is more dangerous because personal data may be accessed or reused across sessions and agents without user awareness, creating privacy, consent, and data-governance risks.
The declared purpose says the skill syncs 'memories across multiple agents,' but the documented behavior includes generic preference storage, remote auto-provisioning via an external API, and local DSN caching. This mismatch is security-relevant because operators may approve a seemingly simple sync utility without realizing it creates external infrastructure and persists connection credentials locally.
The skill writes the full DSN, including username and password, to a file in the user's home directory with no permission hardening or warning. Local attackers, other users on the system, backups, or unrelated processes may be able to read these credentials and gain persistent access to the remote database and its stored data.
The trigger condition is overly broad: ordinary statements like preferences or biographical facts are enough to invoke persistent storage. This can cause the agent to save personal data without sufficiently explicit, informed consent, increasing the chance of over-collection and inappropriate retention across sessions.
The skill declares operational capabilities that include environment access, file read/write, and shell execution, but does not define any tool scope or permission boundaries. In this context, the skill also documents local credential caching and external API/database interaction, so the missing scope increases the chance of overbroad execution and unintended access to secrets or the filesystem.
The description emphasizes convenience and syncing but does not clearly warn that user preferences are transmitted to and stored in an external database service. In a skill dealing with agent settings and preferences, that omission can lead users to place sensitive information into remote storage without informed consent.
Persisting the provisioned database connection in a local file creates cross-session access to a remote datastore and can outlive the user action that created it. In this skill's context, the persisted DSN may grant ongoing access to synced preferences or shared state, making credential theft, unauthorized reuse, and accidental data leakage more likely.
## Security & Provisioning
This skill supports two modes:
1. **BYO Database (Recommended):** Provide `TIDB_*` credentials via environment variables.
2. **Auto-Provisioning (Fallback):** If no credentials are provided, it calls the TiDB Zero API to create a free, ephemeral database and caches the connection locally (`~/.openclaw_hive_mind_dsn`).
## Why use this?
* **Sync:** Update your preferred theme ("Dark Mode") on your Desktop, and your Mobile Agent respects it immediately.
The skill states that it caches the connection locally in ~/.openclaw_hive_mind_dsn, but it does not present this as a prominent security warning or explain the sensitivity of the stored material. A locally cached DSN may expose database endpoints and embedded credentials to other local users, backup systems, logs, or unrelated tooling.
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.
TOOLS.md- **hive-mind**: Store/Retrieve persistent key-value preferences.
- **Location:** `{baseDir}/skills/hive_mind/SKILL.md`
- **Command:** `python {baseDir}/skills/hive_mind/run.py --action set --key "theme" --value "dark"`
The skill silently provisions a remote TiDB instance through an external API, which creates infrastructure and transmits data off-host without explicit user consent. In a skill whose stated purpose is memory sync, this hidden remote resource creation is risky because it can exfiltrate agent data to an unreviewed third-party service and incur unexpected persistence and cost.
The code makes an undisclosed outbound API call to create a remote database instance, which is a significant side effect beyond simple local preference management. Hidden network actions are dangerous in agent skills because they can send operational metadata or future stored content to third parties without user awareness.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
for i in range(3):
try:
cmd = ["curl", "-sS", "-X", "POST", api_url, "-H", "content-type: application/json", "-d", "{}"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if result.returncode == 0:
data = json.loads(result.stdout)
dsn = data.get("instance", {}).get("connectionString")
The manifest describes synchronizing memories across multiple agents using a shared TiDB Zero database. In contrast, the implemented logic only supports set/get/list operations on a single user_prefs table, with no agent identity, synchronization semantics, or memory-sharing behavior; additionally, the code can auto-provision a new database rather than clearly operating on an existing shared one.
The comment claims a security fix using SSL, but the database connection does not enable or verify TLS at all. If the TiDB service is reached over an untrusted network, credentials and synchronized data could be intercepted or modified via man-in-the-middle attacks.
The code creates durable storage for preferences in a shared remote database, causing session data to persist across runs and potentially across agents without any retention policy, scoping, or access controls. In the context of a multi-agent memory skill, that persistence materially increases the risk of unintended cross-agent data exposure and long-lived storage of sensitive information.
with conn.cursor() as cursor:
# Ensure Table Exists
cursor.execute("""
CREATE TABLE IF NOT EXISTS user_prefs (
pref_key VARCHAR(255) NOT NULL PRIMARY KEY,
pref_value TEXT,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
The function accesses TIDB_HOST, TIDB_USER, and TIDB_PASSWORD to construct a DSN, which is sensitive credential handling. The file does not provide a visible warning, prompt, or explanatory comment informing users that environment-based credentials will be consumed.
The design explicitly stores a database connection string in a predictable file under the user's home directory and describes this as persistent behavior, but it does not mention obtaining user consent, warning the user, or addressing local secret exposure risks. A DSN may contain credentials or access tokens, so silently persisting it can leak access to shared memory data to other local processes, users, backups, or dotfile sync systems.
The dependency manifest specifies pymysql without a version constraint, which makes builds non-reproducible and can cause the environment to install different releases over time, including newly introduced vulnerable or breaking versions. In a skill that synchronizes shared memories through a database, dependency drift increases supply-chain risk and can expose all agents using the shared backend to the consequences of a bad release.
pymysql
pymysql has known advisories, and because the manifest does not pin a version, there is no way to verify whether installation will resolve to a fixed or vulnerable release. Given this skill's database-focused purpose, a vulnerable SQL client library is more concerning because it sits directly on the path of database interactions and could increase the likelihood or severity of SQL injection-related compromise depending on how the library is used elsewhere in the skill.
The manifest only states that the skill syncs memories using a shared TiDB Zero database; it does not mention credential discovery from process environment. While common in infrastructure code, reading environment-provided secrets is an additional capability beyond the user-facing purpose described here.