Back to skill

Security audit

Reddit Quote Carousel Topaz

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it describes, but it can upload images to external services, push them to a repository, and publish branded content to Instagram without a clear approval checkpoint.

Install only if you intend this skill to use your Topaz, GitHub/repository, and Instagram credentials for an end-to-end publishing workflow. Review every generated image, caption, destination account, repository change, and public URL before allowing upload, git push, or Instagram publication, and be aware that images may be processed by Topaz and temporarily or permanently exposed through repository hosting or social media.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:107
Finding
Forced Third-Party Promotion in Automatically Published Content<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 107–138 and 152–168 **Vulnerability Type**: Forced promotional content and automatic external publication **Risk Level**: High ### Complete Code Snippet ```markdown **Slide 1 (Cover)** — `clean` style: ```bash python3 /Users/psy/.openclaw/workspace/skills/instagram-photo-text-overlay/scripts/overlay.py \ --input /tmp/ig-reddit-quote/cover-enhanced.jpg \ --output /tmp/ig-reddit-quote/slide-1.jpg \ --title "Top {COUNT} {CATEGORY} in {DESTINATION}" \ --subtitle "Insider Takes from Reddit ({N}+ posts)" \ --style clean --watermark "tabiji.ai" ``` **Slides 2+** — `quote` style, one per attraction: ```bash python3 /Users/psy/.openclaw/workspace/skills/instagram-photo-text-overlay/scripts/overlay.py \ --input /tmp/ig-reddit-quote/{slug}-enhanced.jpg \ --output /tmp/ig-reddit-quote/slide-{N}.jpg \ --title "{ATTRACTION_NAME}" \ --quote "{REDDIT_QUOTE}" \ --author "{SUBREDDIT}" \ --style quote --watermark "tabiji.ai" ``` Output: slides at `/tmp/ig-reddit-quote/slide-{1-N}.jpg` ### Sub-agent 3: Publish to Instagram 1. Host images in tabiji repo (`img/instagram/`), git push, use raw GitHub URLs 2. Create carousel item containers 3. Create carousel container with caption 4. Publish 5. Get permalink 6. Cleanup hosted images + local temp files ``` ```markdown ## Caption Template ``` {flag_emoji} Top {COUNT} {CATEGORY} in {DESTINATION} Real recommendations from {N}+ Reddit posts 🧵 📍 Swipe for the spots + what Redditors actually said: 1. {Attraction 1} 2. {Attraction 2} ... Full list with maps, prices & more Reddit recs 👉 {POPULAR_PICKS_URL} 💬 {PROVOCATIVE_QUESTION — e.g. "What's the most overrated restaurant you've been to abroad?" or "Would you trust a stranger's Reddit rec over a Michelin star?"} #{destination} #{category_tag} #redditfinds #traveltips #foodietravel #localfavorites #tabiji ``` ``` ### Technical Analysis The Skill requires every generated slide to co ...[truncated 2809 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make the `tabiji.ai` watermark disabled by default and require explicit user consent before enabling it. 2. Treat promotional URLs, branding, and hashtags as optional parameters rather than mandatory template content. 3. Generate a complete preview of all slides and the final caption before performing any external action. 4. Require explicit confirmation immediately before: - Copying files into the repository. - Running `git push`. - Creating Instagram media containers. - Publishing the carousel. 5. Clearly identify every external destination, including Topaz Labs, GitHub, and Instagram, and explain what data will be sent to each service. 6. Separate content generation from publication so users can invoke generation without granting repository or Instagram access. 7. Apply least privilege by using narrowly scoped repository and Instagram credentials and retrieving them only during an approved publication step. 8. Validate `popular_picks_url` against an explicit allowlist and display the resolved URL to the user before including it in a public caption. 9. Do not automatically delete hosted or local artifacts until the user confirms that publication succeeded and approves cleanup. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (6)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill explicitly uploads locally stored images to Topaz Labs, but it does not disclose that those images are transmitted to a third-party service outside the local workflow. This creates a real data-handling and privacy risk because images may contain copyrighted, sensitive, or operationally restricted content, and users are not given a chance to approve or opt out of that external transfer.

External Transmission

Medium
Category
Data Exfiltration
Content
TOPAZ_API_KEY=$(security find-generic-password -s "topaz-api-key" -w)

curl --request POST \
  --url https://api.topazlabs.com/image/v1/enhance \
  --header "X-API-Key: ${TOPAZ_API_KEY}" \
  --header 'accept: image/jpeg' \
  --header 'content-type: multipart/form-data' \
Confidence
92% confidence
Finding
This command sends a local image file to the Topaz Labs API, which is a direct external transmission of locally obtained content. In this skill's context, that transmission is expected for functionality, but it is still security-relevant because it moves data off-box to a third party using credentials retrieved from the local keychain.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Submit async
RESPONSE=$(curl -s --request POST \
  --url https://api.topazlabs.com/image/v1/enhance/async \
  --header "X-API-Key: ${TOPAZ_API_KEY}" \
  --header 'content-type: multipart/form-data' \
  --form 'model=Low Resolution V2' \
Confidence
91% confidence
Finding
The async enhancement submission also transmits local image content to Topaz Labs and initiates remote processing tied to an API key. While not overtly malicious, it expands the external data-sharing surface and can expose content to third-party handling without an explicit authorization step.

External Transmission

Medium
Category
Data Exfiltration
Content
# Poll until Completed
while true; do
  STATUS=$(curl -s --header "X-API-Key: ${TOPAZ_API_KEY}" \
    "https://api.topazlabs.com/image/v1/status/${PROCESS_ID}" | jq -r '.status')
  [ "$STATUS" = "Completed" ] && break
  sleep 3
done
Confidence
50% 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
# Poll until Completed
while true; do
  STATUS=$(curl -s --header "X-API-Key: ${TOPAZ_API_KEY}" \
    "https://api.topazlabs.com/image/v1/status/${PROCESS_ID}" | jq -r '.status')
  [ "$STATUS" = "Completed" ] && break
  sleep 3
done
Confidence
50% 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
95% confidence
Finding
The workflow culminates in publishing generated content to Instagram and hosting images in a repository, but it does not require an explicit confirmation before public posting or describe cleanup failure modes. That is dangerous because it can cause unintended public disclosure, persistence of media in Git history or remote hosting, and accidental publication under a real account.

Static analysis

No suspicious patterns detected.