Back to skill

Security audit

Post Deployment Verifier

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its deployment-verification purpose, but its default checks can contact broadly discovered endpoints and read host-wide logs without enough scoping.

Install only if operators will explicitly review target endpoints, avoid running it from privileged or shared hosts, restrict Docker/journal access to the deployment being checked, and avoid authenticated production requests unless the destination and token handling are clear.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:26
Finding

Unbounded Environment-Based Endpoint Discovery Enables Internal Network Probing

Content
View full analysis
/dev/null | head -5) for port in $PORTS; do ENDPOINTS="$ENDPOINTS http://localhost:$port/health http://localhost:$port/healthz" done fi # From kubernetes rg -o "readinessProbe:.*path:\s*(\S+)" -g '*.yaml' -g '*.yml' 2>/dev/null | head -5 # Check each endpoint for endpoint in $ENDPOINTS; do RESPONSE=$(curl -s -o /tmp/health_body -w "%{http_code} %{time_total}s" --connect-timeout 5 --max-time 10 "$endpoint" 2>/dev/null) HTTP_CODE=$(echo "$RESPONSE" | awk '{print $1}') TIME=$(echo "$RESPONSE" | awk '{print $2}') if [ "$HTTP_CODE" = "200" ]; then echo "✅ $endpoint → $HTTP_CODE (${TIME})" elif [ "$HTTP_CODE" = "000" ]; then echo "❌ $endpoint → UNREACHABLE" else echo "⚠️ $endpoint → $HTTP_CODE (${TIME})" cat /tmp/health_body 2>/dev/null | head -3 fi done ``` ### Technical Analysis The Skill scans the complete process environment for variable values associated with broad names such as `URL`, `HOST`, `ENDPOINT`, or `SERVICE`. Every HTTP or HTTPS value discovered this way is automatically converted into four request targets and contacted using the network permissions of the process running the Skill. This behavior is not constrained to the deployment under verification. Environment variables may identify unrelated internal APIs, administrative interfaces, third-party servi ...[truncated 2105 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:135
Finding

Host-Wide Container and System Service Log Reconnaissance

Content
View full analysis
/dev/null; then echo "--- Docker container logs (last 5 min) ---" for container in $(docker ps --format "{{.Names}}" 2>/dev/null); do ERRORS=$(docker logs --since 5m "$container" 2>&1 | grep -ciE "error|exception|fatal|panic" 2>/dev/null) if [ "$ERRORS" -gt 0 ]; then echo "⚠️ $container: $ERRORS errors in last 5 minutes" docker logs --since 5m "$container" 2>&1 | grep -iE "error|exception|fatal|panic" | tail -3 else echo "✅ $container: no errors" fi done fi # Check systemd service logs if command -v journalctl &>/dev/null; then echo "--- Systemd service logs (last 5 min) ---" for svc in $(systemctl list-units --type=service --state=running --no-legend 2>/dev/null | awk '{print $1}' | grep -v systemd); do ERRORS=$(journalctl -u "$svc" --since "5 min ago" --no-pager -q 2>/dev/null | grep -ciE "error|exception|fatal" 2>/dev/null) [ "$ERRORS" -gt 0 ] && echo "⚠️ $svc: $ERRORS errors" done fi ``` ### Technical Analysis The declared purpose is to verify a particular deployment, but the implementation enumerates every running Docker container and nearly every running non-systemd service. It then reads recent logs from those workloads without confirming that they belong to the deployment under review. Access to the Docker daemon commonly provides broad visibility into workloads on the host. Journal access may similarly expose logs from unrelated applications and infrastructure components. Application logs can contain access tokens, credentials, personal data, request content, internal addresses, file paths, and operational details. The Docker branch emits up to three matching raw log lines per container. The systemd branch only ...[truncated 1597 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:44
Finding

Predictable Shared Temporary File Allows Symlink Overwrite and Cross-Run Data Exposure

Content
View full analysis
/dev/null) HTTP_CODE=$(echo "$RESPONSE" | awk '{print $1}') TIME=$(echo "$RESPONSE" | awk '{print $2}') if [ "$HTTP_CODE" = "200" ]; then echo "✅ $endpoint → $HTTP_CODE (${TIME})" elif [ "$HTTP_CODE" = "000" ]; then echo "❌ $endpoint → UNREACHABLE" else echo "⚠️ $endpoint → $HTTP_CODE (${TIME})" cat /tmp/health_body 2>/dev/null | head -3 fi done ``` ### Technical Analysis The response body is written to a constant path, `/tmp/health_body`, in a globally shared temporary directory. The file is not securely created, its ownership and type are not validated, and it is not removed after use. On systems where another local user can create entries in `/tmp`, an attacker may pre-create `/tmp/health_body` as a symbolic link to another file. When `curl -o` opens that path, it may follow the symbolic link and truncate or overwrite the linked file if the Skill's execution account has permission to write it. Concurrent verification runs also share the same path. One execution can overwrite the response body between another execution's request and display operation, causing misleading results or disclosing response content across runs. ### Attack Path 1. A local attacker determines that the Skill uses the predictable path `/tmp/health_body`. 2. Before verification starts, the attacker creates that path as a symbolic link to a file writable by the Skill's execution account. 3. An operator runs the health verification. 4. `curl -o /tmp/health_body` follows the path and writes the endpoint response to the linked target. 5. The target file may be truncated or corrupted with HTT ...[truncated 996 chars]
Remediation
View remediation
/dev/null) ``` If this code is placed inside a larger script or function, lifecycle management should ensure that each process or request receives an independent temporary file. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

md
# Check deployed version via health/status endpoint
for endpoint in $ENDPOINTS; do
  BODY=$(curl -s --connect-timeout 5 "$endpoint" 2>/dev/null)
  DEPLOYED=$(echo "$BODY" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('version',d.get('app_version',d.get('build','?'))))" 2>/dev/null)
  if [ -n "$DEPLOYED" ] && [ "$DEPLOYED" != "?" ]; then
    if [ "$DEPLOYED" = "$EXPECTED_VERSION" ]; then

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill directs users to send requests to discovered endpoints and config-defined URLs, including custom headers such as Authorization, but does not prominently warn that this may contact production systems and transmit sensitive credentials. In context, this is dangerous because endpoint discovery is broad and the config examples encourage bearer token use, creating real risk of secret exposure, accidental production interaction, or SSRF-like behavior against internal services.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger phrase or after any release is overly broad for a skill that performs network calls, reads logs, inspects services, and may interact with production infrastructure. Broad activation increases the chance of unnecessary execution in sensitive environments, causing unintended scans, noisy traffic, and use of privileged local introspection without explicit operator intent.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

else echo "No .deploy-verify.json config found. Create one for automated response validation." echo "Example:" echo ' {"endpoints": [{"url": "https://api.example.com/v1/status", "status": 200, "fields": ["version", "status"]}]}' fi

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

else echo "No .deploy-verify.json config found. Create one for automated response validation." echo "Example:" echo ' {"endpoints": [{"url": "https://api.example.com/v1/status", "status": 200, "fields": ["version", "status"]}]}' fi

text

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This sample config includes an Authorization header for a request to an external-looking API endpoint, normalizing the practice of transmitting bearer tokens during verification. In the broader skill context, which lacks strong warnings and supports arbitrary config-defined URLs, this increases the risk that operators send sensitive credentials to the wrong host or to production services unintentionally.

Content

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

md
"fields": ["status", "version"]
    },
    {
      "url": "https://api.example.com/v1/users",
      "method": "GET",
      "status": 200,
      "headers": {"Authorization": "Bearer ${API_TOKEN}"},

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation claims support for ${VAR} substitution in config, but the implementation sends header values literally. This mismatch can cause failed authentication checks, misleading verification results, and accidental transmission of placeholder secrets or malformed authorization headers to production services.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.