Back to skill

Security audit

querydb-skill

Security checks for vulnerabilities and agentic risk

Overview

The skill’s database-testing purpose is coherent, but it ships live-looking database credentials and business identifiers and includes unsafe database/file-write paths.

Review before installing. Treat the embedded database password and taxpayer identifier as exposed, rotate the credential, replace examples with environment variables or a secret manager, use a read-only least-privilege account, add parameterized SQL, and avoid exporting real invoice or taxpayer data unless explicitly approved.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/db_query.py:547
Finding
Hardcoded Database Credentials Expose Sensitive Test Data<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:20-27, 80-85, 110-115, 158-163`; `scripts/db_query.py:547-553` **Vulnerability Type**: Hardcoded secret and plaintext database credentials **Risk Level**: High ### Vulnerable Code ```python conn = { "host": "10.115.96.247", "port": 3306, "user": "jxindependent", "password": "Xj2zCkLJXTkEJ5j", "database": "jxindependent0", "charset": "utf8mb4" } buyer_tax_no = "91440606MA4WHN8C8X" ``` The documentation also discloses the complete connection parameters: ```text host = 10.115.96.247 port = 3306 database = jxindependent0 user = jxindependent password = Xj2zCkLJXTkEJ5j ``` ### Technical Analysis A live-looking database password is embedded in both the executable script and the Skill documentation. The repository also supplies the corresponding host, port, username, database name, and a taxpayer identifier. Anyone who can read the package can recover everything required to attempt database authentication. Embedding credentials prevents independent secret rotation, makes accidental disclosure through source distribution or logs more likely, and gives every user of the Skill the same database identity. The database account's exact grants are not shown, so the maximum privilege available through this credential cannot be determined from the audited files. ### Attack Path 1. An attacker obtains or reads the Skill package. 2. The attacker extracts the database host, port, username, password, and database name. 3. The attacker establishes network access to `10.115.96.247:3306`, if reachable from their environment. 4. The attacker authenticates using the disclosed credentials. 5. The attacker reads invoice and taxpayer records and, if the account has write privileges, modifies or deletes database data. ### Impact Assessment Successful exploitation can expose invoice numbers, invoice codes, buyer and seller taxpayer identifiers, company names, invoice dates, statuses, and relate ...[truncated 220 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Immediately revoke and rotate the disclosed database password. 2. Remove the password from the script, documentation, examples, version history, release artifacts, and caches. 3. Load credentials at runtime from an approved secret manager or protected environment variables. 4. Use a dedicated read-only database principal limited to the required schemas, tables, columns, and source networks. 5. Avoid including real taxpayer identifiers or production-like records in documentation. 6. Add automated secret scanning to development and release pipelines. 7. Audit database authentication and query logs for previous unauthorized use of the disclosed credential. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/db_query.py:171
Finding
SQL Injection Through Direct Placeholder Substitution<![CDATA[ ## Vulnerability Details **File Location**: `scripts/db_query.py:171-176, 239-245` **Vulnerability Type**: SQL injection **Risk Level**: High ### Vulnerable Code ```python for var_name, var_value in self.variables.items(): sql = sql.replace("{{" + var_name + "}}", str(var_value)) results = db.query(sql) ``` The test-case generator repeats the same unsafe behavior: ```python def _replace_vars(self, sql: str) -> str: """Replace SQL variable placeholders.""" for var_name, var_value in self.variables.items(): sql = sql.replace("{{" + var_name + "}}", str(var_value)) if self.buyer_tax_no: sql = sql.replace("{{buyer_tax_no}}", self.buyer_tax_no) return sql ``` The resulting text is subsequently passed to database query methods that execute it as SQL. ### Technical Analysis Variable values are inserted directly into SQL text instead of being supplied as bound parameters. No escaping, type enforcement, or allowlist validation is applied. Although `DatabaseClient.query()` and `query_one()` accept a `params` argument, these generation paths do not use it. An attacker who controls `variables`, `buyer_tax_no`, or another value passed into a SQL placeholder can introduce quote characters and SQL operators that alter the original statement. Depending on the SQL template, database driver configuration, and account grants, exploitation can bypass predicates, retrieve unrelated records, perform expensive operations, or invoke database-side functionality. Stacked statements may be restricted by the driver, but exploitation does not require stacked statements to disclose additional rows. ### Attack Path 1. A caller supplies an attacker-controlled placeholder value, such as a crafted taxpayer identifier. 2. `_replace_vars()` or `DbFixture._execute()` inserts the value directly into the SQL statement. 3. The modified SQL is passed to `query()`, `query_one()`, or `count()`. 4. The database parses the injected characters as SQL s ...[truncated 643 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace textual value substitution with database-driver placeholders and bound parameters. 2. Have `_replace_vars()` return an SQL template and a separate parameter collection rather than executable SQL text. 3. Validate values such as taxpayer identifiers using strict format and length checks as defense in depth. 4. Never bind table names, column names, or SQL keywords as values. If dynamic identifiers are necessary, select them from a fixed allowlist. 5. Execute the Skill through a read-only database account. 6. Add security tests containing quotes, comments, Boolean expressions, and malformed identifiers to confirm that inputs remain data. 7. Reject unresolved placeholders before query execution. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/db_query.py:120
Finding
Write-Capable Database Interface Exceeds the Skill's Read-Only Requirements<![CDATA[ ## Vulnerability Details **File Location**: `scripts/db_query.py:120-124` **Vulnerability Type**: Excessive database privilege and unrestricted SQL execution **Risk Level**: Medium ### Vulnerable Code ```python def execute(self, sql: str, params: tuple = None) -> int: """Execute INSERT/UPDATE/DELETE and return the affected row count.""" self.cursor.execute(sql, params) self.connection.commit() return self.cursor.rowcount ``` ### Technical Analysis The declared primary functions are database querying, fixture generation, and test-case generation. These workflows only require reading records. Nevertheless, `DatabaseClient` exposes a generic method explicitly designed to execute and commit arbitrary `INSERT`, `UPDATE`, and `DELETE` statements. This unnecessarily expands the authority available to callers and increases the consequences of compromised calling code, malicious inputs, or accidental misuse. Application-level checks would not be sufficient if the configured database principal itself retains write permissions. ### Attack Path 1. A caller imports `DatabaseClient` from the Skill. 2. The caller initializes it with the supplied database connection details. 3. The caller invokes `execute()` with destructive or unauthorized SQL. 4. The method executes the statement and commits the transaction. 5. Database records are modified or deleted according to the account's effective grants. ### Impact Assessment If the configured database account has write grants, an attacker or misbehaving caller can alter or delete all records accessible to that account. Potential consequences include test-data corruption, loss of invoice records, integrity failures, and disruption of systems relying on the database. If the account is strictly read-only, the database should reject these operations, but the repository provides no evidence that such a restriction exists. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `execute()` from this read-oriented Skill unless a documented use case requires data modification. 2. Use a dedicated database principal with only `SELECT` privileges on the minimum required tables and columns. 3. Configure read-only transactions or database-enforced read-only sessions. 4. If generic execution must remain, reject all statements except a narrowly defined set of read operations. 5. Separate read and write clients so that write authority cannot be obtained through the normal fixture-generation interface. 6. Add database auditing and alerts for attempted data-changing statements from the Skill's account. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/db_query.py:83
Finding
Database Connections Do Not Require Certificate-Validated TLS<![CDATA[ ## Vulnerability Details **File Location**: `scripts/db_query.py:83-96` **Vulnerability Type**: Sensitive information transmitted without enforced transport security **Risk Level**: Medium ### Vulnerable Code ```python if self.db_type == "mysql": import pymysql self.connection = pymysql.connect( host=self.host, port=self.port, user=self.user, password=self.password, database=self.database, charset=self.charset, connect_timeout=10 ) elif self.db_type == "postgresql": import psycopg2 self.connection = psycopg2.connect( host=self.host, port=self.port, user=self.user, password=self.password, database=self.database ) ``` ### Technical Analysis The database clients transmit credentials and query sensitive invoice and taxpayer information over the network, but neither connection path explicitly requires TLS or configures certificate and hostname validation. Actual encryption may depend on database-server defaults, client-library behavior, or external configuration. The code does not fail closed when secure transport is unavailable, so the Skill cannot guarantee confidentiality or server authenticity. The network behavior itself is necessary for the declared database-query function, but unverified transport is not necessary and exceeds an acceptable risk level for sensitive data. ### Attack Path 1. The Skill connects to a database across an untrusted, compromised, or incorrectly routed network. 2. TLS is unavailable, optional, or not configured to validate the expected server. 3. A network-positioned attacker observes or interferes with the connection. 4. Depending on the negotiated database authentication and transport behavior, the attacker captures sensitive query results, interferes with traffic, or impersonates the database server. ### Impact Assessment Potential impact includes disclosure of database credentials, invoice identifiers, taxpayer identifiers, company information, and ge ...[truncated 214 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require TLS for both MySQL and PostgreSQL connections. 2. Configure a trusted CA certificate and require server-certificate and hostname validation. 3. For PostgreSQL, use an appropriate strict SSL mode such as `verify-full`. 4. For MySQL, provide validated SSL settings and reject fallback to unencrypted transport. 5. Store CA paths and connection policy in protected configuration rather than disabling verification. 6. Restrict database access with firewall rules, private networking, and source allowlists. 7. Add a startup check that terminates execution if encryption and peer verification are not active. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:63
Finding
Third-Party Database Drivers Are Installed Without Version or Integrity Pinning<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:63-68` **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Medium ### Vulnerable Code ```bash pip install pymysql pip install psycopg2-binary ``` ### Technical Analysis The installation instructions request package names without fixed versions, hashes, or a lockfile. Consequently, separate installations can resolve to different releases. A future compromised, vulnerable, or incompatible release would be installed automatically under these instructions. The packages are referenced by their expected public names, and the audited project contains no evidence of typosquatting, dependency confusion, or an intentionally malicious package. The risk arises from non-reproducible supply-chain resolution and absent integrity verification. ### Attack Path 1. A user follows the documented installation commands. 2. The package installer resolves the latest available release from its configured index. 3. A compromised index, compromised package release, or unsafe mirror supplies altered code. 4. The dependency is installed and later imported by `db_query.py`. 5. Malicious dependency code executes with the privileges of the user running the Skill and may access database credentials and query results. ### Impact Assessment A compromised dependency can execute arbitrary Python code in the Skill process, read database credentials, access generated test data, alter database traffic, and access other resources available to the operating-system user. The practical likelihood depends on package-index integrity and environment configuration. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin reviewed dependency versions in a requirements or lock file. 2. Record and enforce cryptographic hashes, for example with hash-checking installation mode. 3. Install only from an approved package index over authenticated TLS. 4. Regularly scan pinned versions for known vulnerabilities and update them through a controlled review process. 5. Build and test dependencies in an isolated environment before release. 6. Include dependency provenance and reproducible installation instructions with the Skill. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared purpose says the skill is for database querying and validation, but the content also supports fixture injection, automated test-case generation, batch export, and includes live credentials. This mismatch materially increases risk because a reviewer or orchestrator may grant broader trust than warranted, while the skill can access and persist production-like data beyond simple querying.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The documentation contains plaintext database host, username, password, database name, and a business tax identifier. Exposing live credentials and business identifiers can directly enable unauthorized database access, data theft, tampering, or lateral movement, especially because the skill's context is specifically to connect and query that database.

Missing User Warnings

High
Confidence
99% confidence
Finding
The skill exposes live database access details and sensitive test data context without any warning about privacy, authorization, or system access risks. In a database-query skill, this omission is especially dangerous because users may treat the examples as safe defaults and access or disclose regulated business data without proper controls.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The usage example repeats the same live plaintext credentials in runnable sample code, making accidental reuse and credential scraping even more likely. Because these examples are designed to be copied verbatim, they increase the chance of direct unauthorized access and normalize insecure secret handling.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The fixture example propagates the same hardcoded credentials into a workflow that injects real database data into tests. This expands the blast radius from simple disclosure to automated extraction and reuse of sensitive records in downstream test artifacts and systems.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The later generator example again exposes real credentials and also hardcodes a real-looking tax number, tying secret access to identifiable business data. In this context, the skill is not merely generic documentation; it provides enough information to authenticate and query a specific dataset, which significantly heightens exploitation risk.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The skill is presented as query-oriented, but DatabaseClient exposes a generic execute() method that can run INSERT/UPDATE/DELETE and commit changes. In an agent skill context, this expands the trust boundary from read-only data access to destructive database modification, increasing the risk of unintended or unauthorized writes if other components invoke it.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The standalone example embeds what appear to be real database host, username, password, database name, and a real-looking tax identifier directly in source code. Hardcoded credentials can be harvested from the repository or package and used to access live systems and sensitive data, especially dangerous here because the skill connects to external databases and generates artifacts from real records.

Missing User Warnings

High
Confidence
99% confidence
Finding
These lines contain hard-coded database connection secrets without any disclosure or protection mechanism. Anyone with access to the code can recover the credentials and potentially query or modify a live database, leading to data exposure, compliance violations, or downstream compromise.

Lp3

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding
The skill demonstrates file-writing capability via `gen.export_as_json("generated_cases.json")` but does not declare any tool scope or permissions. Undeclared capabilities make the skill harder to sandbox and review, and can lead users or agents to persist sensitive database-derived data unexpectedly.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The example exports generated cases to JSON without warning that the file may contain database-derived sensitive data or may overwrite existing files. Because the generated test cases include mapped real invoice and tax data, silent persistence can create secondary data leaks on disk, in source control, or in shared workspaces.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
Natural-language content throughout the file, including module documentation and later user-visible log strings, is written in Chinese only. There is no indication that the skill is region-specific or that users can opt into this locale, which conflicts with the policy against forcing a specific language without user choice or justification.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The DatabaseClient automatically connects to MySQL or PostgreSQL during initialization and later executes queries against the configured database. While the module describes its purpose, it does not clearly warn users that running the code will establish external database connections and may access real production-like invoice and tax data.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest describes this as a database query skill for connecting to databases, executing SQL, retrieving test data, and validating interface responses. However, the code goes beyond query-oriented behavior by implementing a full TestCaseGenerator that constructs API test-case objects and can write them out as JSON files, which is a broader testing/fixture-generation function than the manifest states.

Missing User Warnings

Medium
Confidence
83% confidence
Finding
The export function writes generated cases, which may include sensitive fields derived from production-like database records, to an arbitrary file path without safeguards. In a testing skill context, this can cause inadvertent local persistence of tax numbers, invoice identifiers, or other business data where filesystem access is broader or retention is uncontrolled.

Static analysis

No suspicious patterns detected.