Back to skill

Security audit

Revdoku Website Publishing

Security checks for vulnerabilities and agentic risk

Overview

This Revdoku publishing skill is mostly coherent, but it should be reviewed because it can publish local folders live, reuse saved credentials, and its helper can download and execute an unpinned CLI.

Install only if you want an agent to manage Revdoku sites. Review the helper script before first use, prefer an already installed or pinned Revdoku CLI, publish with --draft until you are ready to go live, disable analytics/tracking if unwanted, and require explicit confirmation before publish, unpublish, archive, restore, grant exchange, or permanent delete actions.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (9)

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill directs the agent to use shell commands extensively (`revdoku`, `bash`, `curl`, file reads), but no explicit permission boundary is declared. That mismatch is dangerous because a broadly invocable publishing skill can cause real filesystem reads, credential use, and network-side state changes without a clear least-privilege contract.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The invocation guidance is broad enough that common user phrasing about hosting, updating a site, or making local output available could activate a skill that performs real publication actions. In this skill, activation is more dangerous than usual because default behavior includes live publishing and use of saved credentials or local bindings.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The documentation states that `revdoku p` publishes live by default and that analytics/tracking are enabled by default, but it does not lead with a strong user-facing warning about public exposure, telemetry collection, and the risk of publishing unintended files. This creates a high likelihood of accidental data exposure or unexpected tracking when the agent follows the documented default path.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script automatically downloads executable content for both the main CLI and a jq binary, places them in a local bin directory, marks them executable, and then executes them without any user-facing prompt or trust boundary. Although jq is checksum-verified, the revdoku CLI download is not integrity-pinned at all, and both behaviors increase supply-chain risk because a compromised upstream, redirect, or overridden INSTALL_BASE could lead to execution of attacker-controlled code.

External Transmission

Medium
Category
Data Exfiltration
Content
agent_args+=("$value")
  done < <(agent_header_args)

  if ! status="$(curl -sS -o "$body_file" -w "%{http_code}" -X "$method" "$(api_url "$path")" "${agent_args[@]}" -H "Content-Type: application/json" --data "$payload")"; then
    rm -f "$body_file"
    LAST_HTTP_STATUS=""
    LAST_ERROR_CODE="NETWORK_ERROR"
Confidence
90% confidence
Finding
This helper sends arbitrary JSON payloads to a remote Revdoku server using curl, and it is used for authentication, account actions, bucket management, and publication. In this skill's context, external transmission is expected functionality, but it still creates real data exfiltration risk because local content, metadata, API keys in headers, and user-provided values are transmitted off-host to a configurable BASE_URL.

External Transmission

Medium
Category
Data Exfiltration
Content
attempt=0
  while true; do
    body_file="$(mktemp)"
    if status="$(curl -sS -o "$body_file" -w "%{http_code}" -X PUT "${header_args[@]}" --data-binary "@${file}" "$url")"; then
      curl_status=0
    else
      curl_status=$?
Confidence
95% confidence
Finding
This performs direct file upload with --data-binary to a URL supplied by the server, sending local file contents outside the host. That is the core product behavior, but it is still a true exfiltration primitive because any collected file selected by the tool is transmitted to remote storage, and the upload target URL is not independently constrained in the client.

Session Persistence

Medium
Category
Rogue Agent
Content
# Revdoku Website Publishing

Create or update websites in Revdoku as durable bucket files. Publishing is the
default with `revdoku p`: a folder goes live immediately as a public or
password-protected website. Use `--draft` to store files privately without going
live. Re-running `revdoku p` from the same folder updates the same site via a
Confidence
95% confidence
Finding
The skill persists state across sessions through durable bucket storage, local `.revdoku` folder bindings, and saved credentials in `~/.revdoku/credentials`, which can cause later commands to silently target an existing live site or account context. In combination with default live publishing, this persistence materially increases the risk of accidental overwrite, unintended republish, or cross-project data exposure.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
unpublish_bucket() {
  [[ -n "$BUCKET_ID" ]] || die "unpublish requires --bucket-id"
  local response publication_id publish_state status final_response
  response="$(http_json DELETE "/api/v1/buckets/${BUCKET_ID}/publication" "{}")" || return 1
  publication_id="$("$JQ_BIN" -r '.data.publication.id // empty' <<<"$response" 2>/dev/null || true)"
  publish_state="$("$JQ_BIN" -r '.data.publication.publish_state // empty' <<<"$response" 2>/dev/null || true)"
  status="$("$JQ_BIN" -r '.data.publication.status // empty' <<<"$response" 2>/dev/null || true)"
Confidence
86% confidence
Finding
This performs an authenticated destructive action against a bucket selected via BUCKET_ID, which can come from CLI args, environment, or a local .revdoku binding file. In an agent skill context, that is more dangerous because a compromised workspace or mistaken binding could cause the tool to unpublish the wrong site without an additional interactive confirmation step.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
fi

  payload="$("$JQ_BIN" -nc --arg confirmation "$confirmation" '{confirmation:$confirmation}')"
  response="$(http_json DELETE "/api/v1/buckets/${BUCKET_ID}" "$payload")" || return 1
  deletion_started="$("$JQ_BIN" -r '.data.bucket.deletion_started // false' <<<"$response")"
  if [[ "$deletion_started" == "true" ]]; then
    phase="$("$JQ_BIN" -r '.data.delete_progress.phase // "queued"' <<<"$response")"
Confidence
89% confidence
Finding
This issues permanent bucket deletion using a bucket identifier that may be sourced from arguments, environment, or persisted local binding, making it a powerful remote-destruction primitive. Although the server also requires a confirmation token, the client still exposes a high-risk action that an automated agent could trigger on the wrong resource if local state is poisoned or the user intent is misunderstood.

Static analysis

No suspicious patterns detected.