T01 · Skill Instruction Hijacking
- Location
SKILL.md:43- Finding
Unvalidated Semantic Metadata Can Influence Agent Instructions and Generated SQL
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is not overtly malicious, but it needs review because it can access and export business database data while relying on persistent credentials and loosely validated database metadata.
Install only if you can use a dedicated read-only database account limited to necessary tables, a DBA-reviewed _agent_meta semantic model, and a dedicated resource group. Avoid persistent PGPASSWORD where possible, lock down any password files, do not continue past privileged-account warnings for normal use, and review fully expanded SQL before approving execution or CSV export.
SKILL.md:43Unvalidated Semantic Metadata Can Influence Agent Instructions and Generated SQL
references/connection-guide.md:181Windows Setup Guidance Persists Database Passwords in Plaintext Without Enforcing Restrictive ACLs
The document explicitly recommends typing "continue" to bypass a security warning about excessive database privileges. Even though it is labeled a temporary workaround, normalizing warning bypasses can train operators or agents to proceed in unsafe states, undermining the startup safety checks intended to prevent use of overprivileged accounts.
**Temporary Workaround**: Type "continue" to skip the warning, but must fix during the next maintenance window.
The trigger list includes generic terms like 'analyze' and 'statistics' that are common in unrelated conversations, increasing the chance this skill is invoked outside its intended database-query context. In a shell-capable agent, accidental invocation can lead to unnecessary database connectivity checks or query preparation around sensitive systems.
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
- **Prohibited file paths** (in ANY command, script, or code): `.pgpass`, `.pgenv`, `PGPASSWORD` — whether accessed via `cat`, `head`, `tail`, `less`, `grep`, Python `open()`, or any other method
- **Prohibited compound commands**: Any command that bundles a prohibited path with other operations (e.g., `cat ~/.pg_service.conf; cat ~/.pgenv; ls ~/.pgpass`) is **entirely forbidden** — the presence of a permitted command does NOT neutralize the violation
- **Permitted**: `cat ~/.pg_service.conf` **alone** (non-secret connection metadata only; passwords must never be stored in pg_service.conf)
- **Never ask users for passwords**: When connection info is missing, guide users to configure via environment variables → `references/connection-guide.md`
- **Verify connectivity**: Run `psql "service=<service_name>" -c "SELECT 1;"` directly; on failure, guide fixes based on error messages
---
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
rolcreaterole = true → ⚠️ Warning: Current account has role creation permission; DBA should revoke it, keeping only minimum read-only permissions
rolcreatedb = true → ⚠️ Warning: Current account has database creation permission; DBA should revoke itfalse → PASS ✅psql -c "SELECT r.rolname, g.rsgname FROM pg_roles r LEFT JOIN pg_resgroup g ON r.rolresgroup = g.oid WHERE r.rolname = current_user;"
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
rolcreaterole = true → ⚠️ Warning: Current account has role creation permission; DBA should revoke it, keeping only minimum read-only permissions
rolcreatedb = true → ⚠️ Warning: Current account has database creation permission; DBA should revoke itfalse → PASS ✅psql -c "SELECT r.rolname, g.rsgname FROM pg_roles r LEFT JOIN pg_resgroup g ON r.rolresgroup = g.oid WHERE r.rolname = current_user;"
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
│ ▼ [Execution Layer] ├── DB level: Read-only account (no write permissions as fallback) ├── DB level: Resource Group (concurrency/CPU/memory limits) └── Skill level: ≤5 psql calls per turn, SQL displayed for user audit
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Method 4: apt (Debian/Ubuntu, when official package is unavailable)
sudo apt-get install -y postgresql-client
psql --version
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
export PGPASSWORD="<YOUR_PASSWORD_HERE>" # ⚠️ Replace with actual password; prefer ~/.pgpass instead
> More secure approach: Use `~/.pgpass` file (permissions `chmod 600`), format: `host:port:database:user:password`
>
> **⚠️ Security Warning**: Never hardcode passwords in scripts, commit them to version control, or store them in plain-text configuration files without restricted permissions (chmod 600). The recommended approach is `~/.pgpass` (Linux/macOS) or `%APPDATA%\postgresql\pgpass.conf` (Windows) with file permissions limited to the owning user only.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
export PGPASSWORD="<YOUR_PASSWORD_HERE>" # ⚠️ Replace with actual password; prefer ~/.pgpass instead
> More secure approach: Use `~/.pgpass` file (permissions `chmod 600`), format: `host:port:database:user:password`
>
> **⚠️ Security Warning**: Never hardcode passwords in scripts, commit them to version control, or store them in plain-text configuration files without restricted permissions (chmod 600). The recommended approach is `~/.pgpass` (Linux/macOS) or `%APPDATA%\postgresql\pgpass.conf` (Windows) with file permissions limited to the owning user only.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
export PGPASSWORD="<YOUR_PASSWORD_HERE>" # ⚠️ Replace with actual password; prefer ~/.pgpass instead
> More secure approach: Use `~/.pgpass` file (permissions `chmod 600`), format: `host:port:database:user:password`
>
> **⚠️ Security Warning**: Never hardcode passwords in scripts, commit them to version control, or store them in plain-text configuration files without restricted permissions (chmod 600). The recommended approach is `~/.pgpass` (Linux/macOS) or `%APPDATA%\postgresql\pgpass.conf` (Windows) with file permissions limited to the owning user only.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
> More secure approach: Use `~/.pgpass` file (permissions `chmod 600`), format: `host:port:database:user:password`
>
> **⚠️ Security Warning**: Never hardcode passwords in scripts, commit them to version control, or store them in plain-text configuration files without restricted permissions (chmod 600). The recommended approach is `~/.pgpass` (Linux/macOS) or `%APPDATA%\postgresql\pgpass.conf` (Windows) with file permissions limited to the owning user only.
---
The guide instructs users to create persistent local configuration files (~/.pg_service.conf and ~/.pgpass) containing connection metadata and credentials. While common for psql, this creates long-lived secret material on disk and can increase the blast radius if the host, home directory, backups, or developer workspace are later accessed by another process or user. In an agent context, persistent credentials are more sensitive because future agent sessions or unrelated tooling may inherit easy database access.
Completely independent of environment variables; psql automatically reads connection info from files:
Step 1: Create ~/.pg_service.conf
[adbpg]
host=gp-xxx.gpdb.rds.aliyuncs.com
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
- Gate 1 (read-only) is an absolute prerequisite; if not passed, no psql command may be executed
- Gate 3 (semantic model) failure must not be bypassed to continue to gates 4/4b/5/6
- Gate 4b (metric_meta) is a lookup optimization, not a hard gate; absence of metrics does NOT block queries
- **Bypassing gates is prohibited under any circumstances**, including but not limited to: "user needs it urgently", "just this once", "semantic model is only advisory", "let me just \dt for a quick look", "I can infer the table structure myself"
---
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
- Gate 1 (read-only) is an absolute prerequisite; if not passed, no psql command may be executed
- Gate 3 (semantic model) failure must not be bypassed to continue to gates 4/4b/5/6
- Gate 4b (metric_meta) is a lookup optimization, not a hard gate; absence of metrics does NOT block queries
- **Bypassing gates is prohibited under any circumstances**, including but not limited to: "user needs it urgently", "just this once", "semantic model is only advisory", "let me just \dt for a quick look", "I can infer the table structure myself"
---
The decision tree uses broad examples like 'Query data / Analysis' and 'Look up XX' without strict activation qualifiers, which can cause ambiguous routing into this skill. Because the skill performs connection checks and prepares database actions, ambiguous activation can expose metadata or prompt risky operations in contexts not clearly asking for database access.
At L003 the documentation says the agent 'no longer uses \dt or information_schema to discover table structure', implying schema discovery is not part of runtime behavior. However, L029 describes '\d+ table_name' output as the recommended input method that the agent can automatically extract structure from, which contradicts the earlier absolute wording and creates confusion about whether schema discovery is truly avoided or merely shifted to setup time.
The guide repeatedly specifies that display names are Chinese, such as "Chinese display name" and Chinese-language examples in schema comments. This is a natural-language locale preference embedded in the skill documentation, and the file does not state that Chinese is optional, user-selected, or required for a region-specific deployment.
No suspicious patterns detected.