Back to skill

Security audit

JOULE DAO

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a DAO command-line helper, but its setup script embeds a shared API token and automatically performs remote Moltbook actions, which needs review before installation.

Do not run setup.sh unattended. Review and remove the embedded Moltbook token, require explicit consent before any remote create or post action, use your own least-privilege API key, avoid confidential content in discuss or vote messages, and do not use a production wallet private key with this CLI.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/joule.sh:327
Finding
Unverified Remote Installer Piped Directly into a Shell<![CDATA[ ## Vulnerability Details **File Location**: `scripts/joule.sh:327-331` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```bash warn "foundry/cast not installed — cannot sign transaction" echo "" echo " Install foundry for on-chain voting:" echo " curl -L https://foundry.paradigm.xyz | bash" echo " foundryup" ``` ### Technical Analysis The CLI recommends downloading mutable content from an external URL and piping it directly into Bash. Although the project only prints this instruction rather than executing it automatically, users are explicitly directed to run the command when the `cast` dependency is unavailable. The downloaded script is not pinned to a version and is not verified using a cryptographic checksum or signature. Its effective behavior can therefore change after this Skill has been reviewed. Compromise of the remote endpoint, distribution infrastructure, DNS or TLS trust chain could cause arbitrary commands to execute with the invoking user's privileges. Installing Foundry is relevant to the intended on-chain voting feature, but direct `curl | bash` execution exceeds the minimum safe privilege and supply-chain requirements for dependency installation. ### Attack Path 1. A user invokes on-chain voting while `cast` is unavailable. 2. The CLI displays the `curl -L https://foundry.paradigm.xyz | bash` instruction. 3. The user copies and executes the suggested command. 4. A compromised or malicious remote response is passed directly to Bash. 5. The remote payload executes with the user's account privileges. 6. The payload could access local files, wallet configuration, environment variables, or other credentials available to that user. ### Impact Assessment Successful exploitation permits arbitrary code execution under the invoking user's privileges. This may expose Moltbook credentials, wallet-related environment variables, local configuration, source code, SSH credentia ...[truncated 138 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the `curl | bash` installation instruction. - Direct users to an official package manager or versioned release. - Download the installer or binary as a separate step without executing it immediately. - Pin the dependency to a reviewed release version. - Verify the downloaded artifact against a publisher-provided cryptographic signature or checksum. - Use a temporary directory with restrictive permissions for downloaded artifacts. - Require an explicit user confirmation after displaying the source, version, checksum, and requested installation scope. - Prefer a hardware-wallet or documented package-manager workflow that does not require installing mutable remote shell code. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup.sh:14
Finding
Hardcoded Shared Moltbook API Credential<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:14-15`; credential use at `scripts/setup.sh:124-129`, `scripts/setup.sh:146-150`, and `scripts/setup.sh:189-193` **Vulnerability Type**: Hardcoded bearer credential **Risk Level**: High ### Vulnerable Code ```bash # Hardcoded setup API key for creating the submolt SETUP_API_KEY="moltbook_sk_kkWAmIBStGleOs7qYizh0HFU00t5LHz6" ``` The embedded credential is subsequently sent to Moltbook, including in the following operations: ```bash get_response=$(curl -sf "${MOLTBOOK_BASE}/submolts/${SUBMOLT}" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${SETUP_API_KEY}" \ 2>/dev/null || echo "") ``` ```bash http_code=$(curl -s -o /tmp/joule_setup_response.json -w "%{http_code}" \ -X POST "${MOLTBOOK_BASE}/submolts" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${SETUP_API_KEY}" \ -d "$create_data" \ 2>/dev/null || echo "000") ``` ```bash welcome_http=$(curl -s -o /tmp/joule_welcome_response.json -w "%{http_code}" \ -X POST "${MOLTBOOK_BASE}/posts" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${SETUP_API_KEY}" \ -d "$welcome_data" \ 2>/dev/null || echo "000") ``` ### Technical Analysis A bearer token in distributable source must be considered compromised. Every recipient of the Skill can extract and reuse the token outside the intended setup workflow. The credential is used for authenticated operations that inspect or create a remote community and publish content. The setup procedure also mutates shared remote resources automatically. Creating a local configuration file does not require a package-wide remote credential, and community provisioning should be an administrator-controlled operation rather than a side effect performed by every installation. This violates least-privilege principles and prevents reliable attribution of API activity. The audit cannot establish the exact server-side scope or current val ...[truncated 1238 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Revoke and rotate the exposed API token immediately. - Remove the token from the current source and all repository history, releases, archives, logs, and documentation. - Require each user to provide their own narrowly scoped Moltbook credential when authenticated API activity is needed. - Do not create or modify a shared remote community as an automatic installation side effect. - Move one-time community provisioning into a separate administrator-only workflow. - If centralized provisioning is necessary, use a controlled backend that issues short-lived, narrowly scoped credentials rather than distributing a master token. - Apply server-side scope restrictions, expiration, rate limits, audit logging, and origin controls where supported. - Add automated secret scanning to development and release pipelines. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/joule.sh:389
Finding
Predictable Shared Temporary Files Allow Symlink Attacks and Response Disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/joule.sh:389-414`; additional instances at `scripts/setup.sh:146-153` and `scripts/setup.sh:189-196` **Vulnerability Type**: Unsafe temporary-file handling **Risk Level**: Medium ### Vulnerable Code ```bash http_code=$(curl -s -o /tmp/joule_post_response.json -w "%{http_code}" \ -X POST "${MOLTBOOK_BASE}/posts" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${MOLTBOOK_API_KEY}" \ -d "$post_data" \ 2>/dev/null || echo "000") if [[ "$http_code" =~ ^2 ]]; then ok "Posted to m/joule-dao!" echo "" echo -e " ${BOLD}Message:${RESET} $message" echo "" echo -e " View at: ${CYAN}https://www.moltbook.com/m/joule-dao${RESET}" elif [[ "$http_code" == "429" ]]; then local error_body error_body=$(cat /tmp/joule_post_response.json 2>/dev/null || echo "") local retry_msg retry_msg=$(echo "$error_body" | grep -o '"hint":"[^"]*"' | cut -d'"' -f4 || echo "") warn "Rate limited — you can only post once every 30 minutes" [[ -n "$retry_msg" ]] && echo " Hint: $retry_msg" echo "" echo -e " ${DIM}Message saved locally — try again in a few minutes${RESET}" echo -e " ${DIM}Message: $message${RESET}" else local error_body error_body=$(cat /tmp/joule_post_response.json 2>/dev/null || echo "") ``` Setup uses the same unsafe pattern: ```bash http_code=$(curl -s -o /tmp/joule_setup_response.json -w "%{http_code}" \ -X POST "${MOLTBOOK_BASE}/submolts" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${SETUP_API_KEY}" \ -d "$create_data" \ 2>/dev/null || echo "000") create_response=$(cat /tmp/joule_setup_response.json 2>/dev/null || echo "") ``` ```bash welcome_http=$(curl -s -o /tmp/joule_welcome_response.json -w "%{http_code}" \ -X POST "${MOLTBOOK_BASE}/posts" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${SETUP_API_KEY}" \ -d "$welcome_data" \ 2>/dev/null || echo "000") welcome_response=$(cat /tmp/ ...[truncated 1821 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create temporary files with `mktemp` rather than fixed names. - Set `umask 077` before creating files that may contain API responses. - Register a cleanup handler such as `trap 'rm -f "$response_file"' EXIT`. - Quote all generated temporary paths. - Verify that a temporary file is a regular file owned by the current user before reading it. - Avoid persisting responses when possible; capture them directly into shell variables or use a securely created private temporary directory. - Never recommend running these scripts with elevated privileges. - Apply the fix consistently to all three response files in `joule.sh` and `setup.sh`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/joule.sh:318
Finding
Wallet Private Key Passed Through Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/joule.sh:318-324` **Vulnerability Type**: Sensitive credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```bash # castVote(uint256 proposalId, uint8 support) cast send "$CONTRACT_ADDRESS" \ "castVote(uint256,uint8)" \ "$proposal_id" \ "$vote_support" \ --private-key "$JOULE_PRIVATE_KEY" \ --rpc-url "$BASE_RPC" ok "Vote submitted on-chain!" ``` ### Technical Analysis The script passes the complete wallet private key to `cast` as a command-line argument. Command-line arguments can be exposed through process inspection, operating-system accounting, audit frameworks, debugging tools, crash reports, terminal automation, or endpoint telemetry. The current constant uses the zero contract address, so the on-chain branch is not reachable in the reviewed pre-launch configuration. However, this code is explicitly intended to become active after deployment. If activated without redesign, every on-chain vote would place the private key in the child process argument vector. Use of a raw private key is not necessary for the declared voting functionality. Foundry supports safer signer and account workflows, and hardware wallets or encrypted keystores can authorize transactions without exposing a secret in process arguments. ### Attack Path 1. The project updates `CONTRACT_ADDRESS` to a deployed governance contract. 2. A user exports `JOULE_PRIVATE_KEY` and invokes the vote command. 3. The script launches `cast send` with the private key in its command-line arguments. 4. A local process monitor, audit agent, diagnostics system, or sufficiently authorized local user captures the argument vector. 5. The attacker reconstructs the wallet credential from the captured argument. 6. The attacker signs arbitrary transactions independently of the JOULE CLI. ### Impact Assessment Disclosure of the key grants control over the associated wallet, not merely voting function ...[truncated 320 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove support for passing raw private keys through command-line arguments. - Use an encrypted Foundry keystore and named account, hardware wallet, or operating-system credential service. - Prefer an external wallet confirmation flow so the CLI constructs the transaction but does not handle the private key. - Ensure secrets are not exported globally in long-lived shell environments. - Prevent private keys from appearing in logs, error output, process metadata, or debug traces. - Add an explicit security review before activating the on-chain branch. - Document the required signer model and least-privilege transaction flow before replacing the placeholder contract address. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
Findings (24)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
---

### `join`
Display instructions for joining JOULE DAO as a founding member. Includes early-access benefits and how to get your first JOULE.

```bash
./joule.sh join
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

External Script Fetching

High
Category
Supply Chain
Content
warn "foundry/cast not installed — cannot sign transaction"
      echo ""
      echo "  Install foundry for on-chain voting:"
      echo "    curl -L https://foundry.paradigm.xyz | bash"
      echo "    foundryup"
      echo ""
      echo "  Or use a web wallet at: https://www.moltbook.com/m/joule-dao"
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
exit 1
  fi

  check_dep curl "apt-get install curl"
  load_config
  require_moltbook_key
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The script presents itself as a first-time local setup utility, but it also performs authenticated remote actions against a third-party service using a hardcoded credential. This is dangerous because users may run it expecting only local configuration while it silently creates or modifies external resources under the publisher's account, expanding trust and abuse scope far beyond normal setup behavior.

Missing User Warnings

High
Confidence
99% confidence
Finding
The script embeds a live API credential and transmits it to a remote service without a clear warning before use. Hardcoded secrets are dangerous because anyone with access to the repository or artifact can recover and abuse the credential, and users are not given informed consent that the script will immediately authenticate outbound requests.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README tells users to run setup and interaction commands immediately, but does not clearly warn that setup creates local configuration files containing sensitive values and that discussion/join flows may transmit data or post content to an external service. In an agent-facing context, this is risky because automated agents may execute these commands non-interactively, causing unintended disclosure of wallet identifiers, API usage, or public posting without informed consent.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill instructs users to provide a live private key through environment variables for transaction signing, but gives only a vague 'keep safe!' note and no concrete guidance on secure secret handling. In an agent-skill context, encouraging inline private-key configuration can lead to accidental logging, shell history exposure, process-environment leakage, or unsafe reuse of real wallet credentials.

External Transmission

Medium
Category
Data Exfiltration
Content
#### Check ERC-20 balance (balanceOf)
```bash
curl -X POST https://mainnet.base.org \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
bold "DAO Status"
  echo ""

  check_dep curl "apt-get install curl"

  log "Querying Base chain..."
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The vote command can post wallet-linked voting intent off-chain to Moltbook, associating a wallet address with a governance action without a strong warning that this data will be externally published. This can expose user identity, strategy, or participation metadata, which is especially risky for autonomous agents operating with private context.

External Transmission

Medium
Category
Data Exfiltration
Content
EOF
)
      local response
      response=$(curl -sf -X POST "${MOLTBOOK_BASE}/posts" \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer ${MOLTBOOK_API_KEY}" \
        -d "$post_data" \
Confidence
92% confidence
Finding
This POST request transmits content and an Authorization bearer token to Moltbook, creating a real external transmission surface. While intentional, it is still security-relevant because agents may unknowingly send sensitive data or use privileged tokens without sufficient operator awareness or guardrails.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The discuss command sends arbitrary user-supplied message content plus a bearer API token to a third-party service, but the CLI does not present a clear, explicit warning that the content will leave the local environment and be published remotely. In an agent setting, this creates a real risk of unintended disclosure of sensitive prompts, internal data, or operator information through normal command use.

External Transmission

Medium
Category
Data Exfiltration
Content
)

  local response http_code
  http_code=$(curl -s -o /tmp/joule_post_response.json -w "%{http_code}" \
    -X POST "${MOLTBOOK_BASE}/posts" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${MOLTBOOK_API_KEY}" \
Confidence
94% confidence
Finding
This POST sends user content and a bearer token to a remote service and stores the response body in a predictable temporary file under /tmp. The external transmission is intentional, but without strong disclosure and safer local handling it can leak sensitive content or service responses in multi-user environments.

External Transmission

Medium
Category
Data Exfiltration
Content
local call_data="0x70a08231${padded_addr}"

    local response
    response=$(curl -sf -X POST "$BASE_RPC" \
      -H "Content-Type: application/json" \
      -d "{\"jsonrpc\":\"2.0\",\"method\":\"eth_call\",\"params\":[{\"to\":\"${CONTRACT_ADDRESS}\",\"data\":\"${call_data}\"},\"latest\"],\"id\":1}" \
      2>/dev/null || echo '{"error":"RPC call failed"}')
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The comment claims the embedded credential is only for creating the sub-community, but the same credential is later used for posting content as well. This mismatch conceals the real privilege scope of the token and misleads reviewers and users about what remote actions the script can perform.

External Transmission

Medium
Category
Data Exfiltration
Content
fi
}

check_dep curl "required for all network operations"
check_dep jq   "recommended for JSON parsing (apt-get install jq)"
check_dep python3 "recommended for number formatting (apt-get install python3)"
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
ok "Config directory exists: $CONFIG_DIR"
else
  mkdir -p "$CONFIG_DIR"
  chmod 700 "$CONFIG_DIR"
  ok "Created config directory: $CONFIG_DIR"
fi
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
"_comment": "Fill in moltbook_api_key and wallet_address to get started"
}
EOF
  chmod 600 "$CONFIG_FILE"
  ok "Created config template: $CONFIG_FILE"
fi
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The script includes authenticated creation of a remote community and publication of content, but the provided context does not justify why a setup helper needs these capabilities. In an agent skill, hidden or weakly disclosed authenticated external mutations are especially risky because they can be repurposed for unauthorized actions or surprise users with third-party changes.

External Transmission

Medium
Category
Data Exfiltration
Content
)

  create_response=""
  http_code=$(curl -s -o /tmp/joule_setup_response.json -w "%{http_code}" \
    -X POST "${MOLTBOOK_BASE}/submolts" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${SETUP_API_KEY}" \
Confidence
97% confidence
Finding
This POST request creates a remote resource using a hardcoded bearer token. Authenticated outbound creation of third-party resources is dangerous because it mutates external state, can be abused if the token is exposed, and is unexpected in a generic setup script.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script automatically posts a welcome message to a remote community during setup without asking the user to confirm. Unprompted external posting can create unauthorized content, clutter or spam a service, and violate user expectations about what a local setup command should do.

External Transmission

Medium
Category
Data Exfiltration
Content
EOF
)

welcome_http=$(curl -s -o /tmp/joule_welcome_response.json -w "%{http_code}" \
  -X POST "${MOLTBOOK_BASE}/posts" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${SETUP_API_KEY}" \
Confidence
97% confidence
Finding
This POST request publishes content to an external service using the same embedded bearer token. Automatic content publication is dangerous because it creates externally visible actions without user approval and further demonstrates that the exposed credential can perform more than one privileged operation.

Session Persistence

Medium
Category
Rogue Agent
Content
JOULE_DIR="$(cd "${SCRIPT_DIR}" && pwd)"
echo -e "  Add to your shell profile for global access:"
echo ""
echo -e "  ${DIM}# Add to ~/.bashrc or ~/.zshrc:${RESET}"
echo -e "  ${CYAN}export PATH=\"\$PATH:${JOULE_DIR}\"${RESET}"
echo ""
echo -e "  Then use: ${BOLD}joule.sh status${RESET} from anywhere"
Confidence
90% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Low
Confidence
84% confidence
Finding
The skill encourages posting arbitrary discussion content to an external Moltbook API without clearly warning that message contents and associated metadata will be transmitted off-system to a third party. In agent workflows, this can cause unintentional disclosure of sensitive prompts, internal reasoning, proprietary data, or user information if operators assume the command is local-only.

Static analysis

No suspicious patterns detected.