Back to skill

Security audit

database_skill

Security checks for vulnerabilities and agentic risk

Overview

The skill does provide database access as advertised, but it handles saved connection data, credentials, and database-changing commands too loosely for a clean install.

Review before installing. Use only least-privilege database accounts, avoid production mutation unless explicitly intended, avoid --batch for untrusted SQL, do not pass literal passwords or shell-expanded secrets on the command line, do not embed credentials in database URLs, and avoid this on shared machines unless the connection store is moved to a private protected location and TLS is enforced.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/main.py:45
Finding

Database Password Exposure Through Command-Line Arguments

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/connections_store.py:142
Finding

Connection Metadata Stored in a Predictable Temporary File Without Explicit Access Controls

Content
View full analysis
None: self._save_all([]) def _save_all(self, records: List[ConnectionRecord]) -> None: try: with open(self._path, "w") as f: json.dump([r.to_dict() for r in records], f, indent=2) except Exception as exc: logger.debug("Failed to save connections: %s", exc) ``` The records written to that file include connection metadata: ```python def to_dict(self) -> Dict[str, str]: d: Dict[str, str] = { "url": self.url, "username": self.username, "driver": self.driver, "label": self.label, } if self.password_env_var: d["password_env_var"] = self.password_env_var return d ``` ### Technical Analysis The store uses a fixed filename in the system temporary directory. On multi-user systems, this directory is commonly shared. The code writes with ordinary `open(..., "w")` and does not: - Create the file with owner-only permissions. - Verify that the destination is a regular file owned by the current user. - Reject symbolic links. - Use exclusive or atomic file creation. - Separate records belonging to different operating-system users. The resulting permissions depend on the process umask. A typical permissive umask can create a file readable by other local users. If an attacker can pre-create the predictable path as a symbolic link, the write may follow that link and truncate or replace another file that the victim process is authorized to write. No database password value is intentionally placed in this record, but the URL, username, driver, label, and secret environment-variable name are sen ...[truncated 1602 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/main.py:132
Finding

Unredacted Database URLs Are Persisted and Printed

Content
View full analysis
Dict[str, str]: d: Dict[str, str] = { "url": self.url, "username": self.username, "driver": self.driver, "label": self.label, } if self.password_env_var: d["password_env_var"] = self.password_env_var return d ``` ### Technical Analysis The Skill accepts a caller-controlled JDBC URL, preserves the complete string, saves it after successful operations, and later prints it without redaction. The implementation does not reject URL user-info or remove sensitive query parameters. Consequently, a URL containing embedded credentials, tokens, private connection options, or internal host information is persisted even though the documentation states that passwords are never stored. The name of the password-bearing environment variable is also displayed. While this is not the password value, it gives a local attacker useful information for targeting process environments, deployment configuration, ...[truncated 977 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/connection_manager.py:177
Finding

Database Authentication and Query Traffic Are Not Protected by Enforced TLS

Content
View full analysis
:3306/?useSSL=false&charset=utf8mb4 ``` ### Technical Analysis Sending database credentials to the user-selected database server is necessary for the declared connectivity functionality and is not, by itself, evidence of malicious exfiltration. However, the connector does not configure a TLS context, CA trust, certificate verification, or hostname verification. The JDBC query string is parsed only to obtain the hostname, port, and database path. Its TLS-related options are not translated into PyMySQL connection options. Therefore, the insecure `useSSL=false` examples reinforce plaintext transport, while changing that query pa ...[truncated 1528 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • 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 (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Persisting database connection records to a temp-directory JSON file creates a real security concern even if passwords are omitted, because URLs, usernames, hostnames, and driver metadata are sensitive operational information. In multi-user or weakly isolated environments, temp directories may expose connection inventories that aid lateral movement, credential targeting, or reconnaissance against internal databases.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Persisting database connection records to a temp-directory JSON file creates a real security concern even if passwords are omitted, because URLs, usernames, hostnames, and driver metadata are sensitive operational information. In multi-user or weakly isolated environments, temp directories may expose connection inventories that aid lateral movement, credential targeting, or reconnaissance against internal databases.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

Persisting database connection records to a temp-directory JSON file creates a real security concern even if passwords are omitted, because URLs, usernames, hostnames, and driver metadata are sensitive operational information. In multi-user or weakly isolated environments, temp directories may expose connection inventories that aid lateral movement, credential targeting, or reconnaissance against internal databases.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code claims plain-text passwords are never persisted, but to_dict() always serializes the full url, and many database URL formats allow embedded credentials such as user:password@host or password query parameters. This can silently store secrets on disk in a predictable temp-directory file, creating credential exposure to other local users, backup systems, or forensic recovery.

Content

No source excerpt is available for this finding.

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · scripts/query_executor.py (reported line 116)May include surrounding context.

python
self._cm.close_connection(conn)

    def execute_update(self, sql: str, *params: Any) -> int:
        """Execute an UPDATE, INSERT, or DELETE statement.

        Args:
            sql: SQL statement with ``?`` placeholders.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares significant capabilities—environment-variable access, file read/write, and network/database connectivity—but does not define any explicit tool scope or permission boundaries. In an agent setting, this increases the chance of overbroad execution, misuse of credentials, unintended data exfiltration, or destructive database operations because the agent may invoke capabilities beyond what users expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code expands ${VAR} placeholders by reading from process environment variables, which can expose or consume sensitive credentials without any confirmation prompt, user-facing log, or warning comment/docstring about that behavior. For code files, access to sensitive environment variables should have some visible disclosure unless clearly documented elsewhere.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Connection metadata is written to a JSON file in the system temp directory without any explicit disclosure or consent flow. In this skill context, saved records may include sensitive infrastructure details such as internal hosts, database names, usernames, labels, and potentially credentials via the URL, making temp-directory persistence materially riskier than ordinary application state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The CLI explicitly supports UPDATE/INSERT/DELETE operations, and later executes them directly via execute_update without any confirmation prompt or upfront warning about modifying database state. Because these are potentially destructive or irreversible operations, the file should provide some visible disclosure beyond the terse argument help.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The --batch option accepts a file of SQL statements and _do_batch executes them all, which can include destructive changes, but the code provides no confirmation prompt or explicit warning about the risk. This is a safety-critical operation because it can modify or destroy large amounts of data in one run.

Content

No source excerpt is available for this finding.