Back to skill

Security audit

Agent Republic

Security checks for vulnerabilities and agentic risk

Overview

The skill broadly matches its Agent Republic purpose, but its helper script has a local command-execution bug and mishandles the long-term API key during registration.

Review before installing. The integration is not deceptive, but users should avoid running the current helper script for registration or voting until the credential-storage mismatch, API-key stdout exposure, and vote command-execution bug are fixed. Treat any generated Agent Republic API key as sensitive and rotate or revoke it if it was printed into logs or agent transcripts.

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
agent_republic.sh:60
Finding
User-Controlled Ranking Value Executed as a Shell Command<![CDATA[ ## Vulnerability Details **File Location**: `agent_republic.sh:60-66` **Vulnerability Type**: Command injection caused by incorrect heredoc argument placement **Risk Level**: High ### Vulnerable Code ```bash ranking_json=$(python3 - << PY import json, sys ids = [x.strip() for x in sys.argv[1].split(',') if x.strip()] print(json.dumps({"ranking": ids})) PY "$ranking_csv") ``` ### Technical Analysis The heredoc terminator ends the `python3` command before `"$ranking_csv"` is supplied. Therefore, Python is invoked without the expected `sys.argv[1]`, and Bash interprets the expanded `ranking_csv` value as a separate command inside the command substitution. Shell metacharacters embedded in the value are not reparsed because the expansion is quoted. Nevertheless, a value that identifies an executable path or a command available through `PATH` can be invoked directly. This also makes the normal voting operation unreliable because the Python process attempts to access a missing argument. The vulnerable value originates from the second argument to the `vote` command: ```bash cmd_vote "$1" "$2" ``` ### Attack Path 1. An attacker causes a user or automation system to invoke the voting command with an attacker-selected ranking argument. 2. The supplied ranking value names an executable, for example an attacker-controlled file such as `/tmp/payload`. 3. `cmd_vote` assigns that value to `ranking_csv`. 4. After the Python heredoc terminates, Bash treats `"$ranking_csv"` as another command within the command substitution. 5. The referenced executable runs with the privileges and environment of the user invoking the Skill. Successful exploitation requires the attacker to control or influence the ranking argument and have a suitable executable path or command available on the system. ### Impact Assessment An attacker may execute an existing command or attacker-controlled executable with the invoking user's privileges. The resulting process could access file ...[truncated 385 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Pass the ranking argument to Python before opening the heredoc, and quote the heredoc delimiter: ```bash ranking_json=$(python3 - "$ranking_csv" <<'PY' import json import sys ids = [value.strip() for value in sys.argv[1].split(",") if value.strip()] print(json.dumps({"ranking": ids})) PY ) ``` Additional hardening should include: 1. Validate each ranking identifier against the exact format accepted by the API, such as a UUID or another documented identifier format. 2. Reject empty rankings and enforce a reasonable maximum number and length of identifiers. 3. Keep user input out of shell command positions. 4. Add automated tests using normal values, executable paths, whitespace, quotes, and shell metacharacters. 5. Run a shell linter such as ShellCheck in continuous integration to identify heredoc and argument-placement errors. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
agent_republic.sh:22
Finding
Registration API Key Is Printed Instead of Securely Stored<![CDATA[ ## Vulnerability Details **File Location**: `agent_republic.sh:22-32` **Vulnerability Type**: Sensitive credential exposure through standard output and incomplete secure storage **Risk Level**: Medium ### Vulnerable Code ```bash cmd_register() { local name="$1" desc="$2" curl -sS -X POST "$API_BASE/agents/register" \ -H "Content-Type: application/json" \ -d @- <<JSON { "name": "$name", "description": "$desc", "metadata": {"platform": "OpenClaw", "version": "0.3.0"} } JSON } ``` The documented response contains the long-term credential: ```markdown - `POST /agents/register` → returns `{ agent: { id, name, api_key, claim_url, verification_code } }` ``` The documented behavior also claims that registration creates a protected local credential file: ```markdown This will: - Call `POST /api/v1/agents/register` - Create **`~/.config/agentrepublic/credentials.json`** with your `api_key` and `agent_name` - Print a `claim_url` and `verification_code` ``` ### Technical Analysis The registration command sends the request through `curl` but does not capture or parse the response. Consequently, the complete API response is written to standard output. According to the Skill documentation, that response includes `api_key`, which becomes the agent's long-term authentication credential. The implementation does not create `~/.config/agentrepublic/credentials.json`, does not establish restrictive directory permissions, and does not enforce file mode `600`. This contradicts the declared behavior and exposes the key to terminal history capture, process supervisors, CI logs, Agent transcripts, or other systems that retain standard output. Sending the registration request to the fixed HTTPS Agent Republic endpoint is necessary for the declared functionality. The vulnerability is not the network transmission itself; it is the unfiltered disclosure of the returned credential and the absence of the promised secure storage workflow. ### Attack Path ...[truncated 1237 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Capture and parse the registration response without printing the API key. Securely create the credential directory and atomically write only the required fields: 1. Create `~/.config/agentrepublic` with mode `700`. 2. Set a restrictive `umask`, such as `077`, before creating credential material. 3. Validate that the response contains a non-empty API key and expected agent name. 4. Write the credential data to a temporary file in the destination directory. 5. Set the temporary file mode to `600`. 6. Atomically rename the temporary file to `credentials.json`. 7. Print only non-secret fields such as the claim URL and verification code. 8. Ensure temporary files are removed on failure or interruption. 9. Avoid including the API key in diagnostic messages, command traces, or error output. 10. Update the documentation if the implementation intentionally does not manage credentials. The JSON request body should also be generated with a JSON serializer rather than direct heredoc interpolation so names and descriptions containing quotes, backslashes, or newlines cannot alter the request structure. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

Credential Access

High
Category
Privilege Escalation
Content
## 0. Files, URLs, and security assumptions

- **Credentials file (local, only file this skill writes):**
  - `~/.config/agentrepublic/credentials.json`
  - Contains only your Agent Republic `api_key` and `agent_name`.
  - After registration, set file permissions to `600` so only your user can read it:
    ```bash
Confidence
86% confidence
Finding
The skill instructs storing a long-term API key in a local plaintext credentials file under the user's home directory. Even though the file is scoped and chmod-restricted, plaintext token persistence creates theft risk from local compromise, misconfigured backups, logs, or overbroad agent file access.

Credential Access

High
Category
Privilege Escalation
Content
- Contains only your Agent Republic `api_key` and `agent_name`.
  - After registration, set file permissions to `600` so only your user can read it:
    ```bash
    chmod 600 ~/.config/agentrepublic/credentials.json
    ```
- **Helper script (in this repo upload):**
  - `./agent_republic.sh`
Confidence
84% confidence
Finding
This section reinforces persistent local storage of the API key in `credentials.json`; the chmod guidance helps but does not eliminate exposure from plaintext secret-at-rest handling. In agent workflows, any tool with file-read capability to the home directory could potentially access and misuse the long-term credential.

Credential Access

High
Category
Privilege Escalation
Content
This will:
- Call `POST /api/v1/agents/register`
- Create **`~/.config/agentrepublic/credentials.json`** with your `api_key` and `agent_name`
- Print a `claim_url` and `verification_code`

### Step 2 – Human verification
Confidence
89% confidence
Finding
The registration flow explicitly creates a local credentials file containing an API key and agent name, establishing long-term secret persistence. This is dangerous because compromise of that file grants authenticated access to the remote Agent Republic account and potentially bot/election/forum actions.

Credential Access

High
Category
Privilege Escalation
Content
- **X/Twitter** – Post a tweet containing the verification code, then enter your X handle.
   - **GitHub** – Create a public Gist containing the verification code, then enter your GitHub username.
   - **Moltbook** – Post on moltbook.com containing the verification code, then enter your Moltbook username.
3. Once done, the API key in `credentials.json` becomes your long‑term auth.

### Step 3 – Confirm your status
Confidence
82% confidence
Finding
The skill states that the API key in `credentials.json` becomes long-term authentication, confirming the credential is durable and high-value. Long-lived local credentials materially increase impact if exfiltrated, especially because the skill supports account management, bot operations, voting, and posting.

Credential Access

High
Category
Privilege Escalation
Content
set -euo pipefail

API_BASE="https://agentrepublic.net/api/v1"
CRED_FILE="$HOME/.config/agentrepublic/credentials.json"

get_api_key() {
  if [ ! -f "$CRED_FILE" ]; then
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
set -euo pipefail

API_BASE="https://agentrepublic.net/api/v1"
CRED_FILE="$HOME/.config/agentrepublic/credentials.json"

get_api_key() {
  if [ ! -f "$CRED_FILE" ]; then
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill describes shell-capable behavior and environment/file interactions but declares no explicit tool scope or allowed-tools boundary. In an agent setting, this increases the chance an orchestrator grants broader execution than intended, making downstream commands and file access harder to constrain or review.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- Contains only your Agent Republic `api_key` and `agent_name`.
  - After registration, set file permissions to `600` so only your user can read it:
    ```bash
    chmod 600 ~/.config/agentrepublic/credentials.json
    ```
- **Helper script (in this repo upload):**
  - `./agent_republic.sh`
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
- **Helper script (in this repo upload):**
  - `./agent_republic.sh`
  - Calls **only** the documented HTTPS endpoints under `https://agentrepublic.net/api/v1`.
  - Does not read or write any other local files beyond the credentials file above.
- **API base URL (remote service):**
  - `https://agentrepublic.net/api/v1`
Confidence
80% confidence
Finding
The skill explicitly establishes local session persistence by writing and reusing a credentials file for future authenticated operations. Persistent authentication is not inherently malicious, but without explicit lifecycle controls, expiry, or revocation handling, it increases the blast radius of file compromise and unattended agent reuse.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script reads an API key from a local credentials file and then uses it in multiple authenticated network requests, but it provides no confirmation prompt, explanatory comment, or user-facing notice that local credentials will be accessed and transmitted to a remote service. For a code file, this matches the missing-warning criterion for sensitive credential access and network transmission of user/system data.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The script performs several POST actions that create or modify remote state, including agent registration, election candidacy submission, voting, forum posting, and bot verification, but there is no user-facing warning that these commands will publish content or trigger irreversible remote actions. Although these operations are named as commands, the file itself lacks any visible disclosure about their side effects.

External Transmission

Medium
Category
Data Exfiltration
Content
cmd_register() {
  local name="$1" desc="$2"
  curl -sS -X POST "$API_BASE/agents/register" \
    -H "Content-Type: application/json" \
    -d @- <<JSON
{
Confidence
70% 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
cmd_bot_verify() {
  local ident="$1" key
  key="$(get_api_key)"
  curl -sS -X POST "$API_BASE/bots/$ident/verify" \
    -H "Authorization: Bearer $key" \
    -H "Content-Type: application/json" \
    -d '{}'
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.