Back to skill

Security audit

Database Replication Advisor

Security checks for vulnerabilities and agentic risk

Overview

This is a plausible database replication advisor, but it includes live database and cloud failover commands that could disrupt production without strong safeguards.

Install only if you treat this as an operator-reviewed runbook, not an autonomous execution skill. Before using it, restrict credentials to least privilege, run assessment probes in non-production or with explicit approval, avoid command-line database passwords, and require change-management approval before any failover, promotion, rewind, or AWS RDS failover command.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:59
Finding
Environment Variables Injected Directly into Executable Python Source<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 59–90 **Vulnerability Type**: Python code injection through unsafe shell interpolation **Risk Level**: High ### Complete Vulnerable Code ```bash # Application-level heartbeat probe (write timestamp to primary, read from replica) python3 -c " import time, psycopg2 primary = psycopg2.connect(host='$PRIMARY_HOST', dbname='$DB_NAME', user='$DB_USER') replica = psycopg2.connect(host='$REPLICA_HOST', dbname='$DB_NAME', user='$DB_USER') # Write heartbeat to primary with primary.cursor() as cur: cur.execute('CREATE TABLE IF NOT EXISTS _repl_heartbeat (id int PRIMARY KEY, ts timestamptz)') cur.execute('INSERT INTO _repl_heartbeat VALUES (1, now()) ON CONFLICT (id) DO UPDATE SET ts = now()') primary.commit() cur.execute('SELECT ts FROM _repl_heartbeat WHERE id = 1') write_ts = cur.fetchone()[0] time.sleep(0.5) # Read heartbeat from replica with replica.cursor() as cur: cur.execute('SELECT ts FROM _repl_heartbeat WHERE id = 1') read_ts = cur.fetchone()[0] lag = (write_ts - read_ts).total_seconds() if write_ts > read_ts else 0 print(f'Application-level replication lag: {lag:.3f}s') print(f'Assessment: {\"HEALTHY\" if lag < 1 else \"WARNING\" if lag < 10 else \"CRITICAL\"}') " ``` ### Technical Analysis The shell expands `PRIMARY_HOST`, `REPLICA_HOST`, `DB_NAME`, and `DB_USER` directly inside Python string literals before passing the resulting source to `python3 -c`. These values are treated as executable source text rather than as data. If an attacker can influence one of these environment variables, a single quote can terminate the intended Python literal. Additional Python expressions or statements can then be introduced. Because the generated source is executed by `python3`, successful exploitation can run arbitrary local commands with the privileges of the user executing the Skill. This behavior is unnecessary for replication assessment. Python can safely read ...[truncated 1441 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pass connection values as data rather than embedding them into Python source. - Read the existing environment variables through `os.environ`. - Validate hostnames and database names according to strict expected formats. - Use a dedicated, least-privilege monitoring account for the heartbeat operation. - Avoid granting the monitoring account general schema-creation privileges. Provision the heartbeat table separately where possible. A safer pattern is: ```bash python3 - <<'PY' import os import time import psycopg2 primary = psycopg2.connect( host=os.environ["PRIMARY_HOST"], dbname=os.environ["DB_NAME"], user=os.environ["DB_USER"], ) replica = psycopg2.connect( host=os.environ["REPLICA_HOST"], dbname=os.environ["DB_NAME"], user=os.environ["DB_USER"], ) # Continue with the heartbeat check. PY ``` For stronger isolation, implement the probe in a reviewed standalone script and pass secrets through an approved secret manager or protected connection service. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:95
Finding
Database Values Interpolated Directly into SQL Statements<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 95–98 **Vulnerability Type**: SQL injection through unsafe shell-variable interpolation **Risk Level**: High ### Complete Vulnerable Code ```bash # PostgreSQL: check for replication conflicts (queries cancelled on standby) psql -h "$REPLICA_HOST" -U "$DB_USER" -d "$DB_NAME" -c " SELECT datname, confl_tablespace, confl_lock, confl_snapshot, confl_bufferpin, confl_deadlock FROM pg_stat_database_conflicts WHERE datname = '$DB_NAME'; " ``` A similar pattern is also used in the failover pre-flight query near lines 319–325, where a failover target value is inserted into SQL. ### Technical Analysis `DB_NAME` is expanded by the shell inside a quoted SQL literal. The resulting SQL is passed directly to PostgreSQL. If the value contains a quote followed by SQL syntax, it can alter the intended query. Shell quoting does not provide SQL escaping. Even where a value is expected to be a database name, hostname, or IP address, it must not be inserted into SQL as an untrusted string. The database account used for replication assessment may have access to sensitive operational views, and other examples in the Skill require elevated replication or administrative privileges. ### Attack Path 1. An attacker controls or influences `DB_NAME` or another value inserted into an SQL statement. 2. The value includes a quote that terminates the intended SQL string literal. 3. The remainder of the value introduces additional SQL syntax. 4. The operator or AI Agent executes the documented `psql` command. 5. PostgreSQL evaluates the modified statement using the privileges of `DB_USER`. 6. Depending on account permissions and server configuration, the attacker may read unauthorized data, modify database objects, or invoke privileged database functionality. ### Impact Assessment The maximum impact is constrained by the PostgreSQL role used to execute the command. With a properly restricted monitoring role, exploita ...[truncated 612 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not construct SQL by directly inserting shell variables into query text. - Use `psql` variables with PostgreSQL’s safe literal-quoting syntax. - Validate values such as IP addresses using a strict parser before database use. - Run assessment queries through a dedicated read-only monitoring role. - Separate monitoring credentials from failover and promotion credentials. For example: ```bash psql \ -h "$REPLICA_HOST" \ -U "$DB_USER" \ -d "$DB_NAME" \ --set=db_name="$DB_NAME" \ -c " SELECT datname, confl_tablespace, confl_lock, confl_snapshot, confl_bufferpin, confl_deadlock FROM pg_stat_database_conflicts WHERE datname = :'db_name'; " ``` For reusable or complex checks, use a database driver with parameterized queries rather than shell-generated SQL. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:31
Finding
MySQL Password Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 31 **Vulnerability Type**: Sensitive credential exposure in process arguments **Risk Level**: Medium ### Complete Vulnerable Code ```bash # MySQL: check replication status on a replica mysql -h "$REPLICA_HOST" -u "$DB_USER" -p"$DB_PASS" -e "SHOW REPLICA STATUS\G" ``` The same credential-passing pattern is repeated in the MySQL lag and replication-error examples. ### Technical Analysis The password is supplied through the `-p"$DB_PASS"` command-line argument. Command-line arguments can be captured by process inspection, shell tracing, debugging tools, audit systems, command telemetry, or automation logs. Although some MySQL clients attempt to mask passwords in process displays, relying on client-specific masking is not a sufficient secret-handling control. The shell still constructs a process invocation containing the secret, and surrounding automation may record it before masking occurs. Replication credentials are particularly sensitive because they may grant access to replication metadata or replicated data across multiple database instances. ### Attack Path 1. The operator exports `DB_PASS` and executes the documented MySQL command. 2. The shell expands the password into the command-line argument. 3. A local process observer, tracing facility, audit agent, or verbose automation system records the invocation. 4. An attacker with access to those process records or logs obtains the password. 5. The attacker connects to the database using the exposed username and password. 6. The attacker exercises all permissions assigned to that database account. ### Impact Assessment Impact depends on the MySQL account’s privileges and network restrictions. Potential consequences include: - Unauthorized access to replication status and topology metadata. - Disclosure of database data if the account has read privileges. - Replication disruption if the account has administrative replication privil ...[truncated 271 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove passwords from command-line arguments. - Prefer `mysql_config_editor` and a named login path: ```bash mysql_config_editor set \ --login-path=replication-monitor \ --host="$REPLICA_HOST" \ --user="$DB_USER" \ --password mysql --login-path=replication-monitor -e "SHOW REPLICA STATUS\G" ``` - Alternatively, use a temporary or permanent MySQL option file protected with mode `0600`. - Store the credential in an approved secret manager and inject it through a mechanism that does not expose it in process arguments or logs. - Disable shell tracing around commands that handle credentials. - Use a dedicated read-only monitoring account for assessment commands. - Rotate any credentials that may already have been exposed through command history, process telemetry, or CI/CD logs. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (6)

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The `failover-test` workflow goes beyond advisory analysis and includes commands that can alter database roles, stop writes, promote standbys, trigger AWS failover, and rebuild nodes. If an agent executes this in a real environment without strict gating, it can cause service disruption, data divergence, or unintended operational changes.

Missing User Warnings

High
Confidence
99% confidence
Finding
The failover instructions contain disruptive operations such as read-only changes, promotion, cluster failover, and rewinding nodes, yet they are not fronted by strong warnings or execution safeguards. In a production context, that makes accidental outage or data-loss scenarios much more likely, especially when followed by an autonomous agent.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
Including `aws rds failover-db-cluster` grants infrastructure control that can directly change production database topology. For a replication advisory skill, this is overly privileged and expands blast radius from analysis into active cloud control, making accidental or unauthorized failover materially more dangerous.

External Script Fetching

High
Category
Supply Chain
Content
# Should return: t (true = standby)

# Check application connectivity
curl -s "$APP_HEALTH_ENDPOINT" | python3 -c "
import sys, json
data = json.load(sys.stdin)
db_status = data.get('database', {}).get('status', 'unknown')
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The `assess` command is presented as a health check, but its application-level heartbeat probe creates a table and writes to the primary database. That violates the principle of least surprise for a read-only diagnostic action and can modify production state, trigger audit/compliance issues, or fail in restricted environments.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The markdown presents database-writing validation steps as routine assessment without a prominent warning that they modify state. In practice, users or agents may assume the procedure is safe for production diagnostics and execute it without understanding the side effects.

Static analysis

No suspicious patterns detected.