Back to skill

Security audit

PostgreSQL Database

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed PostgreSQL helper, but its included scripts handle credentials, exports, and backups in unsafe ways that deserve careful review before use.

Install only if you are comfortable giving the agent database credentials and authority to run SQL. Use least-privilege database roles, prefer .pgpass or externally supplied environment variables over source .env, avoid running the helper scripts from untrusted directories, and review backup/export destinations before using them on production data.

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/db_backup.sh:8
Finding

Arbitrary Shell Execution Through Unsafe .env Sourcing

Content
View full analysis
/tmp/executed-as-backup-user ``` 3. A user or automation process runs any affected script from that directory. 4. The script executes `source .env`. 5. The injected shell command runs with the operating-system privileges of the invoking account. 6. The attacker can then access files and credentials available to that account or modify subsequent script behavior. ### Impact Assessment Successful exploitation provides arbitrary local command execution as the account running the script. This can expose database credentials, backup contents, SSH or service credentials, and any other files readable by that account. It can also permit file modif ...[truncated 230 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/db_export_csv.sh:24
Finding

Unvalidated Arguments Injected Into a psql \copy Meta-Command

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/db_backup.sh:39
Finding

Database-Controlled Table Names Are Unsafely Embedded in Backup Commands

Content
View full analysis
> "$BACKUP_FILE.tmp" 2>/dev/null || true done ``` ### Technical Analysis Table names are read from the database and processed through unquoted shell command substitution: ```bash for table in $(...) ``` Bash performs whitespace splitting and pathname expansion on the command output. PostgreSQL permits quoted identifiers containing spaces and other unusual characters, so valid table names may be split into multiple values or transformed by shell glob expansion. Each resulting value is then interpolated directly into a `psql` `\copy` meta-command without PostgreSQL identifier quoting. A database principal able to create or rename tables in the `public` schema can therefore influence the command text consumed by a more privileged backup process. Errors are hidden and ignored through `2>/dev/null || true`, which makes exploitation and backup corruption difficult to detect. ### Attack Path 1. An attacker has sufficient database privileges to create or rename a table in the `public` schema. 2. The attacker creates a table with a specially formed quoted identifier containing whitespace or syntax-significant characters. 3. A more privileged operator runs `db_backup.sh`. 4. The table-list query returns the crafted identifier. 5. Bash performs word splitting and possible pathname expansion on that identifier. 6. The resulting text is embedded without identifier quoting in `\copy`. 7. The backup command is mispa ...[truncated 745 chars]
Remediation
View remediation
/dev/null || true`; treat any failed table export as a failed backup. - Record a manifest of expected and successfully exported relations, then verify they match before reporting success. - Restrict table-creation and rename privileges in schemas processed by privileged backup automation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/db_backup.sh:20
Finding

Predictable Temporary Backup File Allows Symlink-Based File Clobbering

Content
View full analysis
"$BACKUP_FILE.tmp" # Export all table structures and data for table in $(PGPASSWORD="${DB_PASSWORD}" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -t -c "SELECT tablename FROM pg_tables WHERE schemaname = 'public';"); do PGPASSWORD="${DB_PASSWORD}" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "\\copy ${table} TO STDOUT WITH CSV" >> "$BACKUP_FILE.tmp" 2>/dev/null || true done gzip -c "$BACKUP_FILE.tmp" > "$BACKUP_FILE" rm -f "$BACKUP_FILE.tmp" ``` ### Technical Analysis The temporary path is derived from the database name and a timestamp with one-second resolution. It is therefore predictable. The script opens the path using ordinary shell redirection, which follows symbolic links and does not require exclusive file creation. If `BACKUP_DIR` is writable by another local user, that user can pre-create a symbolic link at the expected `.tmp` path. When the script performs the first redirection, it follows the link and truncates the linked target if the invoking account has permission to write it. Subsequent append operations then write database export content to that target. The final compressed output path is similarly predictable and opened without exclusive creation, although the `.tmp` path presents the clearest clobbering condition. ### Attack Path 1. A privileged backup process writes to a ...[truncated 1046 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (19)

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

The sample script sources a local '.env' file and then executes arbitrary SQL passed as '$1'. In a skill that explicitly reads credentials and runs user-provided SQL, this increases the risk of credential exposure and destructive or unauthorized database actions if the script is reused without validation, path controls, or least-privilege accounts.

Content

Scanner excerpt · SKILL.md (reported line 236)May include surrounding context.

bash
#!/bin/bash
# scripts/query.sh
source .env
psql -h $DB_HOST -U $DB_USER -d $DB_NAME -c "$1"

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

The backup script sources '.env' to obtain database credentials and writes database dumps to local disk, which can expose secrets and sensitive data if file permissions, execution context, or storage paths are not tightly controlled. In this skill's context, the risk is elevated because it explicitly handles production-style credentials and backup artifacts.

Content

Scanner excerpt · SKILL.md (reported line 245)May include surrounding context.

bash
#!/bin/bash
# scripts/backup.sh
source .env
DATE=$(date +%Y%m%d_%H%M%S)
pg_dump -h $DB_HOST -U $DB_USER $DB_NAME | gzip > backups/${DB_NAME}_${DATE}.sql.gz
find backups/ -mtime +7 -delete  # 保留 7 天

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

Sourcing .env as shell code executes any content in that file with the script's privileges, not just variable assignments. If an attacker can modify .env, they can achieve arbitrary command execution and steal database credentials or tamper with backups; in an agent/automation context this is more dangerous because environment files are commonly writable or injected by surrounding tooling.

Content

Scanner excerpt · scripts/db_backup.sh (reported line 8)May include surrounding context.

sh
set -e

# 加载环境变量
if [ -f .env ]; then
    source .env
fi

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The .env loading pattern enables execution of attacker-controlled shell syntax instead of treating the file as passive configuration. In this backup script, compromise of that file can expose credentials, redirect backups, or run arbitrary commands before any backup logic starts.

Content

Scanner excerpt · scripts/db_backup.sh (reported line 9)May include surrounding context.

sh
# 加载环境变量
if [ -f .env ]; then
    source .env
fi

# 默认值

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The script sources a local .env file as shell code, not as passive configuration. If an attacker can modify that file, they can execute arbitrary commands with the privileges of whoever runs the script, making this more dangerous than merely reading credentials from configuration.

Content

Scanner excerpt · scripts/db_export_csv.sh (reported line 8)May include surrounding context.

sh
set -e

# 加载环境变量
if [ -f .env ]; then
    source .env
fi

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

Loading .env via source causes any shell syntax inside the file to be executed. In this script's context, that can lead to arbitrary code execution before the database export runs, and the presence of database credentials increases sensitivity because secrets may also be exposed or altered.

Content

Scanner excerpt · scripts/db_export_csv.sh (reported line 9)May include surrounding context.

sh
# 加载环境变量
if [ -f .env ]; then
    source .env
fi

# 默认值

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The script sources .env as shell code using source .env, which executes any commands contained in that file, not just variable assignments. If an attacker can modify or replace .env, they can achieve arbitrary command execution in the context of the user running the script and potentially steal database credentials or pivot further.

Content

Scanner excerpt · scripts/db_query.sh (reported line 8)May include surrounding context.

sh
set -e

# 加载环境变量
if [ -f .env ]; then
    source .env
fi

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

This finding refers to the same dangerous behavior: loading .env through shell source, which treats the file as executable shell content. In a skill/script context, this is more dangerous because such helper scripts are often run from cloned repositories or shared workspaces where .env may be attacker-controlled or accidentally tampered with.

Content

Scanner excerpt · scripts/db_query.sh (reported line 9)May include surrounding context.

sh
# 加载环境变量
if [ -f .env ]; then
    source .env
fi

# 默认值

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The entire skill description, usage guidance, and warnings are written only in Chinese, with no indication that another language is available or that Chinese is a required locale. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 76)May include surrounding context.

方式 3: .pgpass 文件(最安全)

echo "主机:端口:数据库:用户:密码" >> ~/.pgpass chmod 600 ~/.pgpass psql -h 主机 -U 用户 -d 数据库

text

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 263)May include surrounding context.

确保允许你的 IP 连接

检查防火墙

sudo ufw status | grep 5432

text

### 权限错误

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file header and usage describe this as a PostgreSQL backup script, and L29 further frames the operation as exporting table structure plus data. In reality, the code at L35-L41 writes only comment lines and then uses \copy ... TO STDOUT WITH CSV for tables in public, which does not capture schema definitions, non-public schemas, indexes, constraints, sequences, roles, or other database objects required for a true backup.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

L39 explicitly states 导出所有表结构 + 数据 (export all table structure + data). However, the loop at L40-L41 only iterates over table names and runs \copy ${table} TO STDOUT WITH CSV, which exports rows only and omits DDL for table definitions and related schema objects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code performs an irreversible file-deletion operation using find ... -delete to remove backups older than 7 days. Although it prints that cleanup is happening, it does not clearly warn the user about deletion impact or offer confirmation before removing files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code performs a file-writing operation that exports database table contents to a user-specified CSV path, but the script only prints the target path and completion status. It does not provide any warning or confirmation that the operation may overwrite an existing file or expose potentially sensitive data from the database.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The natural-language comments and user-facing messages in this script are written in Chinese, with no indication that language choice is configurable or intentionally limited to a specific audience. That can violate language/locale policy when a skill implicitly forces one language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script's natural-language interface, including comments, usage text, and status messages, is exclusively in Chinese. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script's comments and usage output are written only in Chinese, which imposes a specific language choice on users without offering an alternative or opt-in. Under the stated policy, forcing a language or locale without user choice is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code loads a .env file and then passes DB_PASSWORD to psql via PGPASSWORD, which means the script accesses sensitive credentials. While the file has basic usage comments, there is no explicit warning, confirmation, or user-facing notice that credentials from the environment will be consumed.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.