Back to skill

Security audit

DB Readonly

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent database-reporting purpose, but its claimed read-only safety boundary is weak and its export option can overwrite arbitrary local files.

Review before installing. Use only with a dedicated read-only database user or read replica, not an owner/admin account. Do not rely on the script as a hard read-only security boundary, and avoid --out unless the script is changed to restrict exports to a safe directory and prevent overwrites.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/db_readonly.sh:25
Finding

Read-Only SQL Policy Bypass Through Stacked Statements and Incomplete Keyword Filtering

Content
View full analysis
&2 exit 2 fi if ! printf '%s' "$LOWER_SQL" | grep -Eq '^\s*(select|with|explain)\b'; then echo "Blocked: only SELECT/WITH/EXPLAIN statements are allowed." >&2 exit 2 fi ``` The validated SQL is subsequently passed in full to the database clients: ```bash run_postgres() { local psql_cmd=(psql -v ON_ERROR_STOP=1 -X) case "$FORMAT" in table) psql_cmd+=( -P pager=off -c "$SQL" ) ;; csv) psql_cmd+=( -P pager=off -c "\\copy ($SQL) TO STDOUT WITH CSV HEADER" ) ;; tsv) psql_cmd+=( -P pager=off -F $'\t' -A -c "$SQL" ) ;; json) psql_cmd+=( -P pager=off -t -A -c "SELECT json_agg(t) FROM ($SQL) t;" ) ;; *) echo "Unsupported format: $FORMAT" >&2; exit 1 ;; esac ``` ```bash local query="$SQL" if [ "$FORMAT" = "json" ]; then query="SELECT JSON_ARRAYAGG(j) FROM (SELECT * FROM ($SQL) s) j;" fi if [ -n "$OUT" ]; then "${mysql_cmd[@]}" -e "$query" > "$OUT" echo "Saved to $OUT" else "${mysql_cmd[@]}" -e "$query" fi ``` ### Technical Analysis The script treats SQL as read-only when it starts with `SELECT`, `WITH`, or `EXPLAIN` and does not contain one of a limited set of denied keywords. This is not equivalent to parsing SQL or enforcing a single read-only statement. The validation has two fundamental weaknesses: 1. It does not reject statement separators or ensure that the input contains exactly one SQL statement. 2. Its denylist is incomplete ...[truncated 2399 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/db_readonly.sh:17
Finding

Arbitrary Local File Overwrite Through Unrestricted Output Path

Content
View full analysis
"$OUT" echo "Saved to $OUT" else "${psql_cmd[@]}" fi ``` MySQL output is handled in the same manner: ```bash if [ -n "$OUT" ]; then "${mysql_cmd[@]}" -e "$query" > "$OUT" echo "Saved to $OUT" else "${mysql_cmd[@]}" -e "$query" fi ``` ### Technical Analysis The `--out` argument is accepted as an arbitrary filesystem path without validation, path confinement, overwrite protection, or symbolic-link checks. Shell quoting prevents the path itself from becoming shell syntax, but it does not make the file operation safe. The shell opens the redirection target with truncation before launching the database client. Consequently, any existing file writable by the process can be truncated or replaced. A symbolic link can also redirect the write to another writable target. Because redirection occurs before command execution, a target may be truncated even if the database client later fails to connect or execute the query. The vulnerability therefore does not require a successful query result. ### Attack Path 1. An attacker or untrusted caller supplies `--out` with the path of an existing writable file. 2. Alternatively, the attacker identifies or creates a symbolic link whose destination is a sensitive file writable by the Skill process. 3. The script performs shell redirection using `> "$OUT"`. 4. The shell opens and truncates the resolved target before starting `psql` or `mysql`. 5. If the query runs, database output replaces the target contents; if it fails, the target may remain empty or partially written. 6. An ...[truncated 891 chars]
Remediation
View remediation
` redirection. 3. **Defend against symbolic links** - Reject symbolic-link targets. - Open files using mechanisms equivalent to `O_NOFOLLOW`, `O_CREAT`, and `O_EXCL`. - Avoid check-then-write sequences that introduce time-of-check/time-of-use races. 4. **Write atomically** - Create a private temporary file in the destination directory with restrictive permissions. - Write the complete result to that file. - Atomically rename it to an approved, non-existing destination after successful query completion. 5. **Apply restrictive permissions** - Set an appropriate `umask`, such as `077`, before creating files containing query results. - Ensure exports cannot expose potentially sensitive database content to other local users. 6. **Validate failure behavior** - Ensure an unsuccessful database query does not create or truncate the final destination. - Add tests for absolute paths, traversal attempts, existing files, symbolic links, and failed database connections. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script allows query output to be redirected to any user-supplied filesystem path via --out, which expands the skill's effect from database inspection into arbitrary local file creation or overwrite. In an agent setting, that can be abused to clobber files, stage sensitive data in unintended locations, or exfiltrate database contents to shared or monitored paths even though the skill is described as read-only.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script reads sensitive credentials from environment variables, including MYSQL_PASSWORD via MYSQL_PWD and PostgreSQL credentials via required PG* variables later in the file. There is no comment, docstring, or user-facing warning explaining that the skill consumes database secrets from the environment, which meets the missing-warning criterion for code files.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The MySQL branch also writes query results to an arbitrary path supplied by --out without constraining where data may be stored. Although the database query path is nominally read-only, unrestricted filesystem writes let an attacker persist or redirect sensitive query results and potentially overwrite important files accessible to the agent user.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script writes to a user-controlled output path with normal shell redirection, which can create or overwrite files silently. Even if this is intended export functionality, the absence of warnings or overwrite protections makes accidental or adversarial file clobbering plausible in an automated agent workflow.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.