Back to skill

Security audit

db-toolkit

Security checks for vulnerabilities and agentic risk

Overview

This database skill has useful database helpers, but it automatically searches for credentials and relies on risky plaintext and global-install workflows.

Install only if you are comfortable with the agent reading project configuration files for database credentials and connecting to real databases. Prefer supplying a limited, non-production, read-only credential yourself; avoid passing real passwords on the command line; and use a project-local dependency install instead of the documented global npm install.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (5)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:193
Finding
Unpinned Global Dependency Installation Creates a Supply-Chain Execution Risk<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:193-197` **Vulnerability Type**: Unpinned third-party dependencies installed globally **Risk Level**: Medium ### Vulnerable Code ```markdown ### First use (install dependencies) The skill scripts depend on a TypeScript runtime and database drivers, which must be installed globally: ```bash npm install -g tsx mysql2 pg better-sqlite3 ``` ``` ### Technical Analysis The installation command retrieves the latest available versions of four packages without a lockfile, explicit version constraints, integrity hashes, or source verification. An npm installation may execute package lifecycle scripts. Because the packages are installed globally, those scripts run with the privileges of the user invoking npm and can modify the global Node.js environment. The audit found no evidence that the currently named packages are malicious. The vulnerability is the unsafe, mutable supply-chain installation process: a compromised package release, maintainer account, transitive dependency, or registry response could introduce arbitrary code after the Skill has been reviewed. ### Attack Path 1. An attacker compromises a listed package, one of its transitive dependencies, or an associated registry publishing account. 2. The attacker publishes a malicious version containing an installation lifecycle script or malicious runtime code. 3. A user follows the Skill instructions and executes the unpinned global installation command. 4. npm retrieves the compromised version because no known-good version or integrity value is specified. 5. Malicious code executes during installation or when one of the scripts loads the affected package. ### Impact Assessment Successful exploitation can execute code with the privileges of the user running npm. Depending on those privileges, an attacker could access user files and environment variables, alter globally installed Node.js components, steal database credentials later supplied ...[truncated 129 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define reviewed dependencies with exact versions in a local `package.json`. 2. Commit a lockfile and use a reproducible installation command such as `npm ci`. 3. Avoid global installation; execute dependencies from a project-scoped environment. 4. Review dependency provenance and lifecycle scripts before approving upgrades. 5. Use registry integrity verification and automated dependency scanning. 6. Run installation and database utilities under a dedicated, minimally privileged account. 7. Consider disabling lifecycle scripts during installation where the selected packages do not require them. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:77
Finding
Automatic Discovery Reads Credential-Bearing Project Configuration Without Explicit Per-Source Approval<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:77-98`, `SKILL.md:124-138` **Vulnerability Type**: Excessive access to sensitive project configuration **Risk Level**: Medium ### Vulnerable Instructions ```markdown When the user has not provided connection information, first try to discover it automatically from the project: 1. Environment variable files - .env, .env.local, .env.development, .env.production 2. Application configuration files - Spring Boot: application.yml, application.yaml, application.properties - Node.js: config/database.yml, config/database.yaml, knexfile.*, drizzle.config.* - Django: settings.py - Rails: config/database.yml, config/database.yaml - Laravel: .env, config/database.php 3. ORM configuration - Prisma: prisma/schema.prisma - Drizzle: drizzle.config.ts, drizzle.config.js ``` ```markdown Key variable names: - URL form: DATABASE_URL, DB_URL, MYSQL_URL, POSTGRES_URL, spring.datasource.url - Separate form: DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME, DB_DATABASE ``` ### Technical Analysis The Skill directs the Agent to search for and read files commonly containing production passwords, tokens, and unrelated application secrets before asking the user for connection information. Although database discovery is related to the Skill's purpose, recursively reading `.env` and broad framework configuration files can exceed the minimum access necessary for a generic database request. No mechanism limits discovery to a user-selected application, environment, or credential field. Reading an entire configuration file can place unrelated secrets in the Agent context, tool logs, or execution traces. The audit found no code that transmits discovered credentials to an external service, so this finding concerns excessive access and unintended disclosure rather than confirmed exfiltration. ### Attack Path 1. A user makes a general request such as listing database tables without supplying connection ...[truncated 859 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Obtain explicit user authorization before reading each credential-bearing file. 2. Ask the user to select the application and environment before configuration discovery begins. 3. Restrict discovery to a user-approved directory rather than searching an entire repository or monorepo. 4. Extract only explicitly approved database fields and avoid returning complete configuration-file contents to the Agent context. 5. Prefer user-supplied secret references, protected environment variables, or a dedicated credential manager. 6. Display a redacted summary of discovered connection targets and require confirmation before connecting. 7. Never automatically choose a production-looking credential source when development and production configurations coexist. 8. Ensure tool and Agent logs redact passwords, tokens, and connection URL user information. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:239
Finding
Database Passwords Are Passed Through Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:239-250` **Additional Locations**: `references/mysql/connection.md:22-33`, `references/postgresql/connection.md:23-34` **Vulnerability Type**: Plaintext secret exposure through command arguments **Risk Level**: Medium ### Vulnerable Code ```bash tsx $SKILL_DIR/scripts/test-connection.ts --url "mysql://root:secret@localhost:3306/mydb" # Or separate parameters tsx $SKILL_DIR/scripts/test-connection.ts \ --db-type mysql \ --host localhost \ --port 3306 \ --user root \ --password secret \ --database mydb ``` Equivalent password-bearing command patterns are also documented in the MySQL and PostgreSQL connection references. ### Technical Analysis Passwords are supplied either directly through `--password` or embedded in a connection URL passed through `--url`. Command-line arguments can be exposed through shell history, terminal session recording, process inspection, job telemetry, debugging output, audit systems, and command wrappers. The scripts do not intentionally print the supplied password, but avoiding application-level logging does not prevent the shell or operating system from recording process arguments. This behavior conflicts with the Skill's claim that credentials remain limited to the current session. ### Attack Path 1. The Agent obtains a database password from the user or project configuration. 2. It constructs and executes the documented command with the password in an argument. 3. The shell records the command in history, or a local monitoring facility captures the process argument vector. 4. Another local user, administrator, log consumer, or compromised process retrieves the argument. 5. The recovered credential is reused to authenticate to the database. ### Impact Assessment Exploitation exposes the privileges of the compromised database account. A read-only account may disclose database content and schema metadata, while a write-capable or administrative ac ...[truncated 198 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove password-bearing command examples from the Skill documentation. 2. Accept passwords through standard input with terminal echo disabled. 3. Alternatively, accept a reference to a protected environment variable or operating-system credential store instead of the secret value itself. 4. If temporary credential material is unavoidable, use a permission-restricted descriptor or file and delete it reliably after use. 5. Redact credentials from command previews, tool logs, errors, telemetry, and audit output. 6. Warn users against embedding credentials in shell commands or connection URLs. 7. Rotate any real credential that has already been passed through a logged command line. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/test-connection.ts:22
Finding
PostgreSQL TLS Requirement Is Discarded During Connection URL Parsing<![CDATA[ ## Vulnerability Details **File Location**: `scripts/test-connection.ts:22-54`, `scripts/test-connection.ts:80-91` **Additional Locations**: `references/postgresql/connection.md:37-41`, `scripts/list-tables.ts:23-53,79-89`, `scripts/describe-table.ts:39-69,158-168` **Vulnerability Type**: Failure to enforce requested transport encryption **Risk Level**: High ### Vulnerable Code The documentation represents `sslmode=require` as a supported TLS requirement: ```bash # Require SSL tsx $SKILL_DIR/scripts/test-connection.ts --url "postgresql://user:pass@host/db?sslmode=require" ``` The parser discards all URL query parameters: ```typescript function parseConnectionUrl(url: string): ConnectionConfig { if (url.startsWith('sqlite://')) { const path = url.slice(9); const database = path === ':memory:' ? ':memory:' : decodeURIComponent(path); return { dbType: 'sqlite', database }; } const parsed = new URL(url); const protocol = parsed.protocol.replace(':', ''); const dbTypeMap: Record<string, 'mysql' | 'postgresql' | 'sqlite'> = { 'mysql': 'mysql', 'mysql2': 'mysql', 'postgresql': 'postgresql', 'postgres': 'postgresql', 'pg': 'postgresql', }; const dbType = dbTypeMap[protocol]; if (!dbType) { throw new Error(`Unsupported database protocol: ${protocol}`); } return { dbType, host: parsed.hostname, port: parsed.port ? parseInt(parsed.port) : undefined, user: parsed.username, password: parsed.password, database: parsed.pathname.slice(1), }; } ``` The resulting PostgreSQL client configuration does not contain an `ssl` option: ```typescript const { Client } = require('pg'); const client = new Client({ host: config.host, port: config.port || 5432, user: config.user, password: config.password, database: config.database, connectionTimeoutMillis: 10000, }); ``` ### Technical Analysis The URL parser extracts the host, port, user, password, and database but ignores ...[truncated 1427 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Extend `ConnectionConfig` to represent TLS settings explicitly. 2. Parse and validate `sslmode` using `parsed.searchParams`. 3. Map `sslmode=require`, `verify-ca`, and `verify-full` to appropriate `pg` TLS options. 4. Verify server certificates and hostnames by default for remote connections. 5. Reject unsupported security-related URL parameters instead of silently ignoring them. 6. Apply identical TLS parsing and enforcement in `test-connection.ts`, `list-tables.ts`, and `describe-table.ts`. 7. Add tests that verify `sslmode=require` cannot result in a plaintext connection. 8. Consider requiring TLS by default for non-loopback PostgreSQL and MySQL hosts. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/describe-table.ts:261
Finding
SQLite Schema Inspection Interpolates Untrusted Identifiers into PRAGMA Statements<![CDATA[ ## Vulnerability Details **File Location**: `scripts/describe-table.ts:261-305` **Vulnerability Type**: Unsafe SQL identifier construction **Risk Level**: Low ### Vulnerable Code ```typescript async function describeSQLiteTable(config: ConnectionConfig, tableName: string): Promise<TableSchema> { const Database = require('better-sqlite3'); const db = new Database(config.database!); try { const tableInfo = db.prepare(`PRAGMA table_info(${tableName})`).all() as any[]; const columns: ColumnInfo[] = tableInfo.map(r => ({ name: r.name, type: r.type, nullable: !r.notnull, defaultValue: r.dflt_value, })); const primaryKey = tableInfo .filter(r => r.pk > 0) .sort((a, b) => a.pk - b.pk) .map(r => r.name); const indexList = db.prepare(`PRAGMA index_list(${tableName})`).all() as any[]; const indexes: { name: string; columns: string[]; unique: boolean }[] = []; for (const idx of indexList) { if (idx.origin === 'pk') continue; const indexInfo = db.prepare(`PRAGMA index_info(${idx.name})`).all() as any[]; indexes.push({ name: idx.name, columns: indexInfo.map(i => i.name), unique: idx.unique === 1, }); } const fkList = db.prepare(`PRAGMA foreign_key_list(${tableName})`).all() as any[]; const fkMap = new Map<string, { columns: string[]; refTable: string; refColumns: string[]; }>(); ``` ### Technical Analysis `tableName` originates from the command-line `--table` option and is directly interpolated into four SQL statements. Index names retrieved from the database are also interpolated into `PRAGMA index_info(...)`. Neither source is validated or safely quoted as an SQLite identifier. Prepared-statement restrictions may prevent execution of multiple stacked statements, which limits the severity. Nevertheless, crafted names can change SQL parsing, cause unexpected PRAGMA behavior, or repeatedly terminate ...[truncated 1048 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer SQLite table-valued PRAGMA functions that allow values to be supplied through bound parameters where supported. 2. If identifier interpolation is unavoidable, use a dedicated SQLite identifier-quoting function that surrounds identifiers with double quotes and doubles embedded quote characters. 3. Validate user-supplied table names against the table list obtained from `sqlite_master` before issuing schema PRAGMAs. 4. Treat index names read from an untrusted database as untrusted input and quote them identically. 5. Add tests covering spaces, quotes, parentheses, reserved words, Unicode, and deliberately malformed identifiers. 6. Open SQLite files in read-only mode for schema discovery to reduce the consequences of unexpected behavior. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The description presents a broad database operations skill covering connection testing, schema exploration, arbitrary SQL execution, and DDL/DML changes across MySQL/PostgreSQL/SQLite. The actual code only implements one narrow function: describe a specified table's schema. It does connect to the declared database types, but only to fetch metadata for a single table. There is no functionality for executing user-provided SQL, inserting/updating/deleting data, creating or altering schema, or listing tables. This is a material scope mismatch: the declared primary purpose is a general database operations tool, while the code chunk is a table-schema inspection script.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
声明描述的是一个较完整的多数据库操作工具,涵盖连接、Schema 浏览、DDL/DML 和多类数据库管理触发场景。但提供的代码片段只包含 test-connection.ts,其核心功能是测试数据库连接并读取版本号,不支持表结构查询、列出表、执行用户 SQL、插入/更新/删除数据或修改 Schema。虽然“测试数据库连接”属于声明触发场景之一,但代码实际主功能明显比声明范围窄,无法代表所宣称的数据库操作工具整体能力,因此存在描述与实际行为不一致。

Ae1

High
Category
analysis-evasion
Content
- ✅ 使用 `scripts/describe-table.ts` 查询实际数据库中的表结构
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- ✅ 使用 `scripts/describe-table.ts` 查询实际数据库中的表结构
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ssd 3

High
Confidence
98% confidence
Finding
The skill explicitly instructs the agent to automatically search project files such as .env, application.yml, settings.py, and ORM configs for database connection details before asking the user. This is dangerous because those files commonly contain secrets, and the agent is being directed to discover and use credentials without explicit user consent, expanding access to sensitive data and enabling lateral movement into real databases.

Credential Access

High
Category
Privilege Escalation
Content
```
1. 环境变量文件
   - .env, .env.local, .env.development, .env.production

2. 应用配置文件(常见框架)
   - **Spring Boot**: application.yml, application.yaml, application.properties
Confidence
97% confidence
Finding
The guidance specifically targets .env and .env.production files, which are high-probability secret stores for production credentials. In the context of a database skill, instructing an agent to inspect these files materially increases the chance of unauthorized credential access and use against live systems.

Ssd 3

High
Confidence
99% confidence
Finding
The skill goes beyond locating config files and instructs extraction, placeholder resolution, and normalization of sensitive values including database passwords and full connection URLs. That creates a clear credential-handling vulnerability: it operationalizes secret harvesting and makes it easier for the agent to surface, transform, and potentially leak usable credentials.

Credential Access

High
Category
Privilege Escalation
Content
```

```env
# .env
DATABASE_URL=mysql://root:secret@localhost:3306/mydb
```
Confidence
99% confidence
Finding
The example includes a literal DATABASE_URL with embedded username and password, normalizing the practice of extracting and handling plaintext credentials. In a skill designed to connect to databases, this materially increases the risk of credential disclosure, misuse, and accidental propagation into outputs or follow-on commands.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The natural-language description and operational instructions are presented entirely in Chinese, with no indication that the user may choose another language or that the skill is intentionally limited to a Chinese-speaking context. Under the language/locale policy, a forced language without opt-in can be a policy issue unless explicitly justified.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The activation condition "任何涉及数据库 DDL/DML 操作的请求" is extremely broad and does not define clear boundaries for when the skill should or should not activate. Because it lacks exclusions or a constrained trigger list, it could match a wide range of routine conversation about databases and cause unintended invocation.

Intent-Code Divergence

Medium
Confidence
88% confidence
Finding
Lines L021-L023 present the skill as non-persistent and not writing files, creating an expectation of minimal local side effects for handling connection information. However, L194-L215 instructs global package installation and modification of the shell environment via NODE_PATH, which are persistent host-level changes and contradict the '不写入任何文件/不持久化存储' framing as written.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The examples explicitly place database passwords on the command line and normalize this as standard usage. Command-line secrets can be exposed through shell history, process listings, audit logs, CI job output, and shared terminal recordings, which creates a real credential leakage risk for a database-access skill.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This markdown file includes `DROP TABLE IF EXISTS users;` and `TRUNCATE TABLE users;`, which can delete data or schema state, but the surrounding documentation provides no warning about irreversibility, data loss, or the need to verify the target environment first. Under the markdown-specific warning criteria, examples that affect user data or system integrity should be accompanied by clear cautionary language.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The file includes destructive SQL operations such as DELETE and TRUNCATE with no accompanying warning about irreversible data loss, backup requirements, or safe execution practices. In a skill explicitly triggered for live DDL/DML database operations, these examples can be copied directly into production-like contexts and increase the chance of accidental mass deletion.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The documentation includes example commands that place the database password directly on the command line and inside a connection URL. Command-line arguments can be exposed through shell history, process listings, logs, and audit tooling, which can leak credentials to other local users or monitoring systems. In a database-operation skill, this is more dangerous because users are likely to copy-paste the examples verbatim with real production credentials.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The documentation includes destructive SQL examples such as DROP TABLE ... CASCADE and TRUNCATE without adjacent warnings about irreversible data loss or guidance to verify environment/backup status first. In a database-operation skill, users are likely to copy commands directly into real systems, which increases the chance of accidental production data deletion.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This markdown file documents data-modifying and data-deleting SQL operations, including broad updates and deletes such as updating inactive users and deleting multiple rows. Under the markdown-file criteria, the description should warn that these commands can alter or remove user data if run against a real database, but no such warning is present near the examples.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation includes destructive SQLite DELETE examples, including deleting all rows and resetting sqlite_sequence, without any warning about irreversible data loss, backups, or transaction safeguards. In a skill explicitly designed to help users execute DDL/DML against live databases, such examples can be copied directly into production contexts and cause accidental mass deletion.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The usage examples explicitly encourage passing the database password on the command line, which can leak secrets through shell history, process listings, audit logs, and orchestration telemetry. In a database administration skill, exposing credentials is especially risky because those credentials may grant broad access to production data and schema metadata.

Missing User Warnings

Medium
Confidence
82% confidence
Finding
The MySQL connection code initiates a network connection using supplied host, user, and password values, and similar behavior exists for PostgreSQL. While connecting to a database is part of the script's purpose, there is no explicit warning in code comments or CLI help that credentials and schema queries will be sent to a remote database server.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
This code opens whatever path is supplied in config.database for SQLite, which performs local filesystem access. Although the script header explains usage, it does not warn users that providing a SQLite database path will cause the tool to open and inspect a local file.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The file's natural-language description, usage notes, and output explanation are presented exclusively in Chinese. Under the policy, forcing a specific language without offering a user choice or documenting a justified locale constraint is a natural-language policy violation.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This code opens outbound MySQL connections using host, user, password, and database parameters, which sends potentially sensitive connection data to a remote system. Although network access is central to the script's purpose, the file does not include any user-facing warning or disclosure that credentials and connection metadata will be transmitted to the specified server.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The PostgreSQL client is configured with host, user, password, and database values and then connects to a remote endpoint. The script lacks any comment or user-facing warning that running it will contact an external server and use the provided credentials during that connection attempt.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
SQP-3 applies to all file types and covers language or locale policy violations. This file presents all instructions in Chinese only, with no indication that the skill is region-specific or that users may choose another language, which can amount to an undocumented forced language constraint.

Static analysis

No suspicious patterns detected.