Back to skill

Security audit

90-day-social-generator

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it advertises, but it needs review because it uses client data, AI providers, web-host credentials, public uploads, insecure FTP, and a default local SSH key path.

Review before installing. Use this only with client data you are allowed to send to the selected AI and image providers. Prefer SSH with an explicitly provided limited-purpose key, avoid FTP, avoid passing secrets directly on the command line, and verify upload destinations because generated images may become public.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill advertises capabilities that involve environment variables, filesystem writes, network access, and shell execution, but does not declare permissions or provide an explicit capability boundary. That makes the operational risk opaque to users and reviewers, increasing the chance that sensitive credentials, local files, or remote systems are accessed without informed consent.

Intent-Code Divergence

High
Confidence
97% confidence
Finding
The module docstring explicitly claims there is no SSH or server upload, but the code later implements both SSH/SCP and FTP upload functionality. This discrepancy can mislead reviewers and operators into underestimating the script's network and credential-handling behavior, increasing the chance of unsafe deployment or accidental data exfiltration.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README explicitly promotes FTP as a supported upload method for generated images and accepts credentials via `--ftp-user`/`--ftp-pass` without warning that standard FTP transmits credentials and file contents in cleartext. In this skill’s context, users are likely to upload content to client web hosts over untrusted networks, so an attacker on the network path could intercept hosting credentials and tamper with uploaded files or public image assets.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill sends client website content, business details, and likely derived marketing data to third-party LLM and image providers, but the description does not clearly warn users that this data leaves their environment. This creates privacy, confidentiality, and compliance risk, especially if client details or site content contain sensitive or regulated information.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The skill uploads generated images to a web host and writes public URLs into the output CSV, but it does not prominently warn that those assets will become publicly accessible. Users may unintentionally expose branded, client-specific, embargoed, or otherwise sensitive media on an internet-reachable host.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script accepts sensitive secrets such as LLM API keys, SSH keys, and FTP passwords directly via command-line flags. On many systems, command-line arguments are exposed through shell history, process listings, audit logs, and orchestration tooling, which can leak credentials to other local users or logging systems.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script can upload generated images to remote systems over SSH or FTP and construct public URLs, but it does not clearly disclose that client content and generated assets may be transmitted to external hosts. In this skill context, that increases the risk of unintended data exfiltration, especially because client-specific content is being generated and published.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script supports plain FTP, which transmits credentials and content without transport encryption. In a workflow that uploads generated client assets to hosting, this exposes usernames, passwords, and uploaded content to interception or manipulation by a network attacker.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The script sends client-identifying business data, location data, company description, website, and sitemap-derived URLs to an external LLM service without any explicit runtime consent, minimization, or disclosure controls. In a client-services workflow, this can expose proprietary or sensitive customer information to third-party processors and create compliance and confidentiality risks.

External Transmission

Medium
Category
Data Exfiltration
Content
print("ERROR: no LLM key. Pass --llm-key (the only env var in this package is HIGHLEVEL_ACCESS_TOKEN).", file=sys.stderr)
        sys.exit(2)
    model = llm_model or "deepseek-chat"
    base = llm_base or "https://api.deepseek.com/chat/completions"
    body = json.dumps({
        "model": model,
        "messages": [{"role": "user", "content": prompt}],
Confidence
88% confidence
Finding
This code performs external transmission of generated prompts containing client data to a third-party endpoint by default. In this skill context, that is more sensitive than generic outbound traffic because the prompt includes customer business metadata and site structure, so using a remote AI API has privacy, contractual, and data-governance implications.

Unvalidated Output Injection

High
Category
Output Handling
Content
import subprocess
    conn = ["-i", key, "-o", "ConnectTimeout=15", "-o", "StrictHostKeyChecking=accept-new"]
    dest = f"{user}@{host}:{remote_path}"
    r = subprocess.run(["scp"] + conn + [local, dest], capture_output=True, text=True)
    if r.returncode != 0:
        raise RuntimeError(f"scp failed: {r.stderr[-300:]}")
Confidence
75% confidence
Finding
Although subprocess is invoked without a shell, scp interprets destination syntax itself, and unvalidated host/user/remote_path values can still cause unintended outbound transfers or option-like argument confusion. In the context of an agent skill that may process external/client-supplied configuration, this creates a realistic risk of sending files to attacker-controlled infrastructure.

Credential Access

High
Category
Privilege Escalation
Content
user, host = ssh_host.split("@", 1)
        else:
            user, host = (args.ssh_user or "root"), ssh_host
        key = args.ssh_key or os.path.expanduser("~/.ssh/id_rsa")
        upload_fn = lambda local, remote: ssh_upload(host, user, key, local, remote)
        upload_host = host
        print(f"    upload via SSH: {user}@{host}:{args.ssh_remote_dir}", file=sys.stderr)
Confidence
93% confidence
Finding
Defaulting to ~/.ssh/id_rsa means the script will automatically attempt to use the operator's private SSH key if upload is enabled and no explicit key is provided. In an agent/automation context, silently reaching for a sensitive local credential increases the risk of unintended credential use, especially when combined with user-controlled destination parameters.

Static analysis

No suspicious patterns detected.