Back to skill

Security audit

Gotchi DAO Voting

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but it can submit real DAO votes using signing authority and has under-scoped credential and endpoint handling that users should review carefully.

Install only if you intend this skill to cast real Aavegotchi Snapshot votes from the configured wallet. Use dry-run first, verify the proposal ID, choice, wallet, space, and endpoints, and prefer setting BANKR_API_KEY explicitly for this skill rather than relying on cross-skill Bankr config discovery.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/lib.sh:37
Finding

Signed Vote Authorization Can Be Sent to an Untrusted Configurable Endpoint

Content
View full analysis
/dev/null } ``` The selected configuration file can also be overridden through an environment variable: ```bash CONFIG_FILE="${GOTCHI_DAO_CONFIG_FILE:-$SCRIPT_DIR/../config.json}" ``` After obtaining a valid Bankr signature, the script sends the signed payload to the unvalidated endpoint: ```bash jq -n \ --arg address "$WALLET" \ --arg sig "$SIGNATURE" \ --slurpfile data "$TMP_TYPED" \ '{address:$address,sig:$sig,data:$data[0]}' > "$TMP_PAYLOAD" VOTE_RESPONSE="$(curl -sS -X POST "$SEQUENCER" -H "Content-Type: application/json" -d @"$TMP_PAYLOAD")" ``` ### Technical Analysis The `snapshotSequencer` configuration value is only checked for non-emptiness. The code does not verify its scheme, hostname, port, or origin before sending a security-sensitive payload to it. The transmitted payload contains: - The user's wallet address. - The complete EIP-712 typed vote. - The vote choice and proposal identifier. - A valid Bankr-generated signature authorizing that exact vote. The bundled configuration points to the legitimate `https://seq.snapshot.org/` endpoint. However, a modified `config.json` or attacker-controlled `GOTCHI_ ...[truncated 1926 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code accurately supports the 'check active Aavegotchi DAO proposals' portion of the description by querying active proposals from Snapshot and displaying proposal details plus wallet voting power. However, this code chunk does not perform any voting action, does not prepare or submit a vote, and does not use Bankr or EIP-712 signatures. Since the declared description includes a significant capability—voting via Bankr EIP-712 signatures—that is absent from the supplied code, the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `./scripts/vote.sh [--dry-run] <proposal-id> <choice>`

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README tells the user to run a live vote submission command immediately after a dry-run preview, but it does not clearly warn that this sends a real governance vote using the user's signing authority. In a DAO governance context, an accidental vote can have meaningful political and financial consequences and may be difficult or impossible to retract depending on Snapshot/space behavior.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill declares shell-capable behavior and external dependencies (curl, jq) but does not define any explicit tool scope such as permissions or allowed-tools. In agent environments, missing scope boundaries can allow broader-than-intended command execution or make it unclear what runtime capabilities are required, increasing the chance of misuse or unsafe invocation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function resolves a Bankr API key not only from its own environment but also from unrelated local skill configuration paths under ~/.openclaw. That creates cross-skill secret access and violates least privilege: this voting skill can silently consume credentials provisioned for another skill, which increases the blast radius if the skill is modified or compromised.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script loads a sensitive API key from environment and local files with no prompt, disclosure, or consent boundary, so operators may not realize this skill is harvesting existing secrets from their session or filesystem. In an agent-skill setting, silent secret discovery is risky because it enables unexpected credential use and makes abuse harder to notice.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · scripts/lib.sh (reported line 83)May include surrounding context.

sh
payload="$(jq -n --arg query "$query" --argjson variables "$variables_json" '{query:$query,variables:$variables}')" || err "Failed to build Snapshot query payload"

  curl -sS -X POST "$SNAPSHOT_API" \
    -H "Content-Type: application/json" \
    -d "$payload"
}

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · scripts/vote.sh (reported line 219)May include surrounding context.

sh
echo "📝 Signing vote with Bankr..."
SIGN_PAYLOAD="$(jq -n --slurpfile typed "$TMP_TYPED" '{signatureType:"eth_signTypedData_v4",typedData:$typed[0]}')"

SIGN_RESPONSE="$(curl -sS -X POST "https://api.bankr.bot/agent/sign" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d "$SIGN_PAYLOAD")"

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · scripts/vote.sh (reported line 219)May include surrounding context.

sh
echo "📝 Signing vote with Bankr..."
SIGN_PAYLOAD="$(jq -n --slurpfile typed "$TMP_TYPED" '{signatureType:"eth_signTypedData_v4",typedData:$typed[0]}')"

SIGN_RESPONSE="$(curl -sS -X POST "https://api.bankr.bot/agent/sign" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d "$SIGN_PAYLOAD")"

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · scripts/vote.sh (reported line 242)May include surrounding context.

sh
--slurpfile data "$TMP_TYPED" \
  '{address:$address,sig:$sig,data:$data[0]}' > "$TMP_PAYLOAD"

VOTE_RESPONSE="$(curl -sS -X POST "$SEQUENCER" -H "Content-Type: application/json" -d @"$TMP_PAYLOAD")"

echo "📬 Response:"
echo "$VOTE_RESPONSE" | jq '.'

Static analysis

No suspicious patterns detected.