Back to skill

Security audit

Genviral

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Genviral social-media automation wrapper, but it also recommends unattended self-updates that replace its own instructions and scripts from an unsigned remote branch.

Review this skill carefully before installing. Use it only with a Genviral key and connected accounts you are comfortable automating, disable or avoid the daily self-updater unless you manually review diffs first, avoid unattended posting until you add an explicit approval step, and keep API keys in a tightly controlled environment rather than a shared global env file.

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/update-skill.sh:71
Finding
Automatic Self-Update Replaces Trusted Instructions and Executable Scripts with Unverified Remote Content<![CDATA[ ## Vulnerability Details **File Location**: `scripts/update-skill.sh:71-113`; automatic scheduling is recommended in `docs/setup.md:202-211` **Vulnerability Type**: Remote payload retrieval and execution through an unsigned self-update mechanism **Risk Level**: High ### Vulnerable Code ```bash # Fetch latest commit SHA from GitHub API (no git required) # Resolve GitHub token (explicit env var, or from gh CLI) GH_TOKEN="${GITHUB_TOKEN:-$(gh auth token 2>/dev/null || echo "")}" REMOTE_SHA=$(curl -sf \ -H "Accept: application/vnd.github.v3+json" \ -H "Authorization: Bearer $GH_TOKEN" \ "https://api.github.com/repos/fdarkaou/genviral-skill/commits/$REMOTE_BRANCH" \ | jq -r '.sha' 2>/dev/null || echo "") if [[ -z "$REMOTE_SHA" ]]; then echo "ERROR: Could not fetch remote SHA. Check network or GITHUB_TOKEN." exit 1 fi echo "Remote SHA: $REMOTE_SHA" if [[ "$CURRENT_SHA" == "$REMOTE_SHA" && "$FORCE" != "true" ]]; then echo "Already up to date. Nothing to do." exit 0 fi echo "Update available! Applying..." UPDATED_FILES=() FAILED_FILES=() for FILE in "${SKILL_OWNED_FILES[@]}"; do RAW_URL="https://raw.githubusercontent.com/fdarkaou/genviral-skill/$REMOTE_SHA/$FILE" TARGET="$SKILL_DIR/$FILE" if [[ "$DRY_RUN" == "true" ]]; then echo "[DRY RUN] Would update: $FILE" continue fi # Fetch and write atomically TMPFILE=$(mktemp) if curl -sf "$RAW_URL" -o "$TMPFILE"; then mkdir -p "$(dirname "$TARGET")" mv "$TMPFILE" "$TARGET" # Make scripts executable [[ "$FILE" == scripts/* ]] && chmod +x "$TARGET" UPDATED_FILES+=("$FILE") echo " ✓ Updated: $FILE" else rm -f "$TMPFILE" # File may not exist in remote (optional file) — not a hard error FAILED_FILES+=("$FILE") echo " - Skipped (not found in remote): $FILE" fi done ``` The setup documentation recommends executing this updater every day: ```bash openclaw cron add \ --name "Genviral: Daily Skill Update" \ --cron "0 6 * * *" ...[truncated 3106 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable unattended updates by default, especially updates to `SKILL.md` and files under `scripts/`. 2. Require explicit user or administrator approval before applying an update. 3. Download proposed updates into a staging directory and display a complete diff before replacement. 4. Publish signed releases and verify signatures against a public key pinned in the installed package. 5. Alternatively, verify every file against a manifest whose digest is independently pinned or administrator-approved. 6. Do not treat a commit identifier obtained from the same mutable repository as an independent trust anchor. 7. Separate documentation updates from executable and instruction updates; apply stricter approval requirements to scripts and `SKILL.md`. 8. Preserve and verify restrictive ownership and permissions on replacement files. 9. Record the old and new trusted version identifiers in an audit log and support rollback. 10. If automated checks are necessary, allow the scheduled job to report that an update exists without applying it. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/genviral.sh:192
Finding
Global Environment File Is Executed as Arbitrary Shell Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/genviral.sh:192` **Vulnerability Type**: Unsafe shell sourcing of a writable configuration file **Risk Level**: Medium ### Vulnerable Code ```bash load_defaults() { # Load env file if available [[ -f "${HOME}/.config/env/global.env" ]] && source "${HOME}/.config/env/global.env" 2>/dev/null || true API_KEY="${GENVIRAL_API_KEY:-}" BASE_URL="$(config_get base_url "https://www.genviral.io/api/partner/v1")" DEFAULT_PACK_ID="$(config_get default_pack_id "")" DEFAULT_SLIDE_COUNT="$(config_get default_slide_count "5")" DEFAULT_ASPECT_RATIO="$(config_get default_aspect_ratio "4:5")" DEFAULT_TYPE="$(config_get default_type "educational")" DEFAULT_STYLE="$(config_get default_style_preset "tiktok")" DEFAULT_LANGUAGE="$(config_get language "en")" DEFAULT_ACCOUNT_IDS="$(config_get default_account_ids "")" DEFAULT_PRIVACY="$(config_get privacy_level "PUBLIC_TO_EVERYONE")" DEFAULT_POST_MODE="$(config_get post_mode "DIRECT_POST")" HTTP_CONNECT_TIMEOUT="$(config_get connect_timeout "10")" HTTP_MAX_TIME="$(config_get max_time "120")" HTTP_RETRIES="$(config_get retries "2")" HTTP_RETRY_DELAY="$(config_get retry_delay "2")" } ``` ### Technical Analysis The Bash `source` builtin does not parse an environment file as passive key-value data. It evaluates the complete file as shell syntax in the current process. Command substitutions, function declarations, redirections, process launches, and arbitrary commands contained in the file are executed immediately. The file is named `global.env`, indicating that it may be shared with unrelated tools. Consequently, compromise or unsafe modification by another local component becomes a code-execution path whenever any `genviral.sh` command is invoked. Redirecting stderr to `/dev/null` can also conceal errors or indicators generated by malicious statements. The Skill only needs `GENVIRAL_API_KEY`; executing a ...[truncated 1338 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `source "${HOME}/.config/env/global.env"` operation. 2. Prefer requiring `GENVIRAL_API_KEY` to be supplied directly through the process environment or a dedicated secret manager. 3. If file-based configuration is required, use a Skill-specific file rather than a global shared file. 4. Parse only an exact allowlist of keys as data; never evaluate the file as shell syntax. 5. Reject lines containing shell metacharacters, command substitutions, redirections, or unsupported assignments. 6. Validate the API-key format before use. 7. Require the secret file to be owned by the invoking user and reject group- or world-writable permissions. 8. Avoid suppressing parser and permission errors that could indicate tampering. 9. Document the file’s security requirements and recommend restrictive permissions such as mode `0600`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/genviral.sh:192
Finding
Configurable API Base URL Can Redirect the Genviral Bearer Credential<![CDATA[ ## Vulnerability Details **File Location**: `scripts/genviral.sh:192-253` **Vulnerability Type**: Credential disclosure through an unrestricted configurable network destination **Risk Level**: Medium ### Vulnerable Code ```bash load_defaults() { # Load env file if available [[ -f "${HOME}/.config/env/global.env" ]] && source "${HOME}/.config/env/global.env" 2>/dev/null || true API_KEY="${GENVIRAL_API_KEY:-}" BASE_URL="$(config_get base_url "https://www.genviral.io/api/partner/v1")" DEFAULT_PACK_ID="$(config_get default_pack_id "")" DEFAULT_SLIDE_COUNT="$(config_get default_slide_count "5")" DEFAULT_ASPECT_RATIO="$(config_get default_aspect_ratio "4:5")" DEFAULT_TYPE="$(config_get default_type "educational")" DEFAULT_STYLE="$(config_get default_style_preset "tiktok")" DEFAULT_LANGUAGE="$(config_get language "en")" DEFAULT_ACCOUNT_IDS="$(config_get default_account_ids "")" DEFAULT_PRIVACY="$(config_get privacy_level "PUBLIC_TO_EVERYONE")" DEFAULT_POST_MODE="$(config_get post_mode "DIRECT_POST")" HTTP_CONNECT_TIMEOUT="$(config_get connect_timeout "10")" HTTP_MAX_TIME="$(config_get max_time "120")" HTTP_RETRIES="$(config_get retries "2")" HTTP_RETRY_DELAY="$(config_get retry_delay "2")" } ``` ```bash api_call() { local method="$1" local endpoint="$2" local body="${3:-}" local url="${BASE_URL%/}${endpoint}" local curl_args=( -sS --connect-timeout "$HTTP_CONNECT_TIMEOUT" --max-time "$HTTP_MAX_TIME" --retry "$HTTP_RETRIES" --retry-delay "$HTTP_RETRY_DELAY" -X "$method" -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" -w '\n%{http_code}' ) [[ -n "$body" ]] && curl_args+=(-d "$body") local response response="$(curl "${curl_args[@]}" "$url" 2>&1)" || { die "Request failed: curl error for $method $endpoint" } ``` The configuration path is sele ...[truncated 2360 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Hardcode or strictly allowlist the official authenticated API origin, such as `https://www.genviral.io`. 2. Parse the URL using a reliable URL parser and validate scheme, hostname, port, and path independently. 3. Reject plaintext HTTP and all unexpected ports, user-information components, and non-allowlisted hosts. 4. Do not send the production Bearer credential when a custom endpoint is selected. 5. If development endpoints are necessary, require a separate development credential and explicit opt-in. 6. Require interactive confirmation before first use of any nonstandard endpoint. 7. Warn and terminate if `GENVIRAL_CONFIG` points to a file with unsafe ownership or permissions. 8. Add automated tests proving that credentials cannot be forwarded to alternate hosts. 9. Align the YAML parser with the documented nested configuration format to eliminate ambiguous fallback behavior. ]]>

other

Warning
Location
scripts/genviral.sh:3454
Finding
Full Pipeline Posts Content Without Enforcing the Declared Visual Review Gate<![CDATA[ ## Vulnerability Details **File Location**: `scripts/genviral.sh:3454-3473` **Vulnerability Type**: Unsafe autonomous publishing caused by a non-enforced approval control **Risk Level**: Medium ### Vulnerable Code ```bash # ----- Step 3: Review ----- echo "" >&2 step "Step 3/4: Review rendered slideshow" local review_result review_result="$(cmd_review --id "$slideshow_id" --json)" || die "Pipeline failed at review step." # ----- Step 4: Post ----- local post_id="" if [[ "$skip_post" == true ]]; then echo "" >&2 step "Step 4/4: Skipped (--skip-post)" else echo "" >&2 step "Step 4/4: Post as draft" local post_result post_result="$(cmd_post_draft --id "$slideshow_id" --caption "$caption" --account-ids "$account_ids")" || die "Pipeline failed at post step." post_id="$(printf '%s' "$post_result" | jq -r '.id // ._id // .post.id // empty')" fi ``` The declared safety requirement in `SKILL.md:141-144` states: ```markdown 2. **ALWAYS visually review every rendered slide** before posting. If any slide fails readability, fix it. This is a hard gate — not a suggestion. ``` ### Technical Analysis The pipeline labels a slideshow-detail retrieval operation as “Review.” `cmd_review --json` obtains and returns slideshow data, but the pipeline does not: - Open or analyze each rendered image. - Ask the user to inspect the slides. - Obtain an explicit approval decision. - Validate a signed or stateful approval record. - Evaluate readability or safety criteria. - Stop posting when review criteria fail. The only enforced condition is whether the API retrieval succeeds. After successful retrieval, the pipeline proceeds directly to `cmd_post_draft`. Although the current function posts through the draft-oriented command rather than necessarily publishing publicly, this still creates or transfers content to a connected social-media workflow. The behavior does not satisf ...[truncated 1395 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make `--skip-post` the default for the end-to-end pipeline. 2. Display or open every rendered slide before allowing the posting stage. 3. Require an explicit user confirmation after rendering, including the slideshow identifier and target account. 4. In autonomous environments, require a separate approval artifact generated by a trusted visual-review component. 5. Record the reviewer, timestamp, reviewed image digests, and decision so that approval cannot be reused after content changes. 6. Invalidate approval whenever a slide, caption, account, or render is modified. 7. Enforce readability and policy checks as actual conditional gates rather than informational steps. 8. Clearly distinguish metadata retrieval from visual review in command names and logs. 9. Preserve draft-only and restrictive privacy defaults unless the user separately authorizes public publication. 10. Add integration tests ensuring that posting cannot occur when review is absent, incomplete, or failed. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (44)

Self-Modification

High
Category
Rogue Agent
Content
scripts/
    genviral.sh             # 42+ commands wrapping every Partner API endpoint
    update-skill.sh         # Self-updater (keeps skill files current, never touches workspace/)

  prompts/
    slideshow.md            # Prompt templates for slideshow generation
Confidence
95% confidence
Finding
Documenting and encouraging a self-updater for an agent skill is a real self-modification risk because it permits code and instruction changes after initial installation. Given this skill can post to social accounts and influence agent behavior through updated scripts and SKILL/docs content, a compromised updater or source repo could lead to unauthorized actions, credential misuse, or persistent malicious behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared purpose focuses on social media automation, but the skill also includes self-updating behavior, remote GitHub fetches, local file modification, and other operational capabilities not surfaced in the primary description. This mismatch is dangerous because users and orchestration systems may trust the skill for one purpose while it performs supply-chain-relevant actions that can alter its own code or environment.

Self-Modification

High
Category
Rogue Agent
Content
scripts/
    genviral.sh             # Main API wrapper (all commands)
    update-skill.sh         # Self-updater
```

## Command Routing
Confidence
96% confidence
Finding
The presence of a self-updater means the skill can modify its own scripts and documentation after installation. Self-modification is dangerous because it enables supply-chain compromise, persistence, and post-review behavior changes, especially when updates are pulled from a remote repository rather than a pinned, verified artifact.

Self-Modification

High
Category
Rogue Agent
Content
## Auto-Updates

This skill includes a self-updater that keeps skill-owned files in sync with the latest version from `fdarkaou/genviral-skill`.

```bash
bash scripts/update-skill.sh           # check + apply if updates available
Confidence
99% confidence
Finding
The auto-update section explicitly instructs execution of a script that checks for and applies remote updates to skill-owned files. In this context, that creates a direct path for remote code and behavior changes outside the original review boundary, making the skill materially more dangerous than a static API wrapper.

Ae1

High
Category
analysis-evasion
Content
**What gets updated (skill-owned):** `SKILL.md`, `scripts/`, `docs/` (all subdirs)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
Assign best-matching image to each slide. Build a `pinned_images` map.

### 5. Prompt Assembly
Use the selected hook and visual direction to build a slideshow prompt. Reference `workspace/content/scratchpad.md` and `docs/prompts/slideshow.md`.

### 6. Generate WITH Pinned Images
```bash
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
# Slideshow Prompt Templates

Use these templates when generating slideshows via the genviral API. Before using any template:
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Self-Modification

High
Category
Rogue Agent
Content
--cron "0 6 * * *" \
  --tz "YOUR_TIMEZONE" \
  --session isolated \
  --message "Run the genviral skill self-updater: bash scripts/update-skill.sh. It will check for updates to SKILL.md, scripts/, and docs/ from the upstream repo and apply them. Never touches workspace/. Report what was updated or confirm already up to date." \
  --announce
```
Confidence
98% confidence
Finding
The daily self-updater instructs the agent to run a script that pulls and applies upstream changes to SKILL.md, scripts/, and docs/ automatically. This is dangerous because it enables remote self-modification of the skill's behavior and trusted instructions without human review, potentially introducing malicious logic, altered prompts, or unsafe commands into future runs.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
analytics-target-create         POST /analytics/targets
  analytics-target                GET /analytics/targets/{id}
  analytics-target-update         PATCH /analytics/targets/{id}
  analytics-target-delete         DELETE /analytics/targets/{id}
  analytics-target-refresh        POST /analytics/targets/{id}/refresh
  analytics-refresh | get-analytics-refresh
                                  GET /analytics/refreshes/{id}
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
require_arg "id" "$pack_id"
    warn "Deleting pack $pack_id..."

    api_call DELETE "/packs/${pack_id}" >/dev/null

    ok "Pack deleted."
}
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
warn "Deleting image $image_id from pack $pack_id..."

    api_call DELETE "/packs/${pack_id}/images/${image_id}" >/dev/null

    ok "Image deleted from pack."
}
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
require_arg "id" "$template_id"
    warn "Deleting template $template_id..."

    api_call DELETE "/templates/${template_id}" >/dev/null

    ok "Template deleted."
}
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
require_arg "id" "$slideshow_id"
    warn "Deleting slideshow $slideshow_id..."

    api_call DELETE "/slideshows/${slideshow_id}" >/dev/null

    ok "Slideshow deleted."
}
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
warn "Deleting analytics target $id..."

    local response
    response="$(api_call DELETE "/analytics/targets/${id}")"

    ok "Analytics target deleted"
    printf '%s' "$response" | jq '.data'
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The README promotes automated posting, analytics collection, and strategy adjustment without clearly warning that prompts, media, account identifiers, and performance data will be transmitted to third-party services. In a skill designed for cross-platform publishing and analytics, unclear disclosure raises privacy and consent risks, especially if agents act on behalf of users or organizations.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The README claims a mandatory visual review 'hard gate' before posting, but the Quick Start later shows a direct render and create-post flow with no enforced review step. This mismatch can cause operators or downstream agents to assume safety checks exist when they do not, increasing the chance of unintended or harmful content being published automatically.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The Quick Start includes live posting commands against connected accounts without a conspicuous caution that they can immediately publish content publicly. In an automation skill, runnable examples are likely to be copied verbatim by users or agents, so omission of a warning materially increases the risk of accidental publication and reputational harm.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The README advertises a self-updating mechanism that can overwrite skill-owned files such as SKILL.md, scripts, and docs. In an agent-skill context, this expands the trust boundary from the local checked-in code to whatever remote source the updater fetches, creating a supply-chain and self-modification risk if the repository or update channel is compromised.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill advertises shell-backed automation but does not declare an explicit tool scope such as permissions or allowed-tools. That creates an overbroad execution surface where an agent may invoke shell commands beyond what a user would reasonably infer from the metadata, increasing the chance of unintended command execution or abuse through prompt-driven routing.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The configuration sets `language: "en"` as a fixed default, which can impose a specific language/locale behavior without indicating user choice or region-specific justification. This is a natural-language policy concern because it may cause the skill to operate in English regardless of the user's preferred language.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation exposes a destructive command that deletes analytics targets without any warning about permanence, scope, or the need for explicit user confirmation before execution. In an automation-oriented skill, this increases the chance that an agent or user invokes deletion accidentally or as part of a broader workflow, causing loss of tracked account configuration and disrupting analytics operations.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation exposes a destructive `delete-pack` command with no warning that it permanently removes user-managed content, and no guidance to verify the target ID before execution. In an automation-oriented skill, operators may copy/paste commands or let agents invoke them, increasing the chance of accidental deletion of packs and downstream content loss.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The `delete-pack-image` command is documented as a simple removal action without cautioning that it deletes pack contents and may disrupt slideshow generation or existing workflows that depend on those images. Because this skill is designed for full content-pipeline automation, omission of deletion safety guidance makes accidental or scripted data loss more likely.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The workflow explicitly publishes content to external social media accounts and logs persistent identifiers such as account_id, post_id, platform, and engagement metrics, but the documentation provides no user-facing consent, confirmation, or safety warning before these actions. In an agent skill, this is dangerous because a user or higher-level orchestrator could trigger real posting and tracking behavior with reputational, privacy, and operational consequences that are not clearly surfaced at the decision point.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The documentation exposes bulk post-deletion commands without any warning about destructive impact, confirmation prompts, or safer usage guidance. In an automation skill for cross-platform publishing, this increases the likelihood of accidental or scripted mass deletion of scheduled, draft, or active content, especially when users copy-paste examples directly into production workflows.

Static analysis

No suspicious patterns detected.