Back to skill

Security audit

Personal Brand Builder

Security checks for vulnerabilities and agentic risk

Overview

The skill broadly fits a personal brand workflow, but it deserves review because it can use existing credentials for external Telegram updates and social automation while some sensitive write paths are under-declared.

Install only if you are comfortable with the skill storing brand strategy, contacts, proof, and audit data in the workspace and sending summaries to Telegram when credentials are present. Review or disable automation before connecting social posting credentials, and add tighter path/network controls if your OpenClaw environment supports them.

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
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (28)

Tainted flow: 'req' from os.environ.get (line 73, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
97% confidence
Finding

The skill performs outbound network transmission to Telegram using environment-provided bot credentials and sends operational/user data off-host. This creates an exfiltration channel for identity, activity summaries, and business metadata, and the feature is not clearly disclosed or gated by explicit user consent.

Content

Scanner excerpt · brand_manager.py (reported line 77)May include surrounding context.

python
f"https://api.telegram.org/bot{token}/sendMessage",
            data=payload.encode(), headers={"Content-Type": "application/json"}
        )
        with urllib.request.urlopen(req, timeout=10):
            pass
        print(f"  ✅ Telegram notification sent")
    except Exception as e:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 14)May include surrounding context.

md
## Credentials required

- `TELEGRAM_BOT_TOKEN` — already in agent .env
- `TELEGRAM_CHAT_ID` — already in agent .env
- `TWITTER_API_KEY` — for Twitter/X automation (developer.twitter.com)
- `TWITTER_API_SECRET` — for Twitter/X automation

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 15)May include surrounding context.

md
## Credentials required

- `TELEGRAM_BOT_TOKEN` — already in agent .env
- `TELEGRAM_CHAT_ID` — already in agent .env
- `TWITTER_API_KEY` — for Twitter/X automation (developer.twitter.com)
- `TWITTER_API_SECRET` — for Twitter/X automation

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 561)May include surrounding context.

md
## Credentials required

- `TELEGRAM_BOT_TOKEN` — already in agent .env
- `TELEGRAM_CHAT_ID` — already in agent .env
- `TWITTER_API_KEY` — for Twitter/X automation (developer.twitter.com)
- `TWITTER_API_SECRET` — for Twitter/X automation

Credential Access

High
Category
Privilege Escalation
Confidence
82% confidence
Finding

The skill explicitly notes that Telegram bot credentials are already present in the agent .env while also defining autonomous notification behavior and outbound network access. In this context, informing the agent about available secrets increases the risk of those credentials being accessed and used for unintended messaging or data exfiltration, especially since the skill logs sensitive operational summaries and sends Telegram updates.

Content

Scanner excerpt · SKILL.md (reported line 562)May include surrounding context.

AGENT ALREADY HAS: TELEGRAM_BOT_TOKEN → already in agent .env TELEGRAM_CHAT_ID → already in agent .env

text

### Bootstrap Checklist

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises broad capabilities through metadata and instructions—reading/writing workspace files, using environment credentials, and making network requests—without declaring a clear restrictive tool scope such as permissions or allowed-tools. This creates ambiguity for the runtime and reviewers, increasing the chance the skill is granted broader access than users expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill is designed to use Telegram and social-media APIs with multiple credentials and to send notifications or content externally, but it does not clearly warn users about privacy, third-party data sharing, or secret-handling risks. In a brand-management skill, external posting and message delivery can expose sensitive business metrics, contact data, and draft content if users do not understand what leaves the workspace.

Content

No source excerpt is available for this finding.

Scope Creep

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation instructs the skill to store screenshots, testimonials, revenue data, and other proof artifacts under /workspace/brand/proof/, but that directory is not included in the declared allowed write paths. This mismatch can lead to failed operations, unsafe permission expansion later, or users granting broader write access ad hoc to make the skill work.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill persistently writes identity, networking, proof, audit, and learning data into workspace files without an explicit user-data warning. Because these files may contain personal branding strategy, contact lists, testimonials, revenue screenshots, and behavioral logs, users may unknowingly accumulate sensitive data in predictable locations.

Content

No source excerpt is available for this finding.

Tainted flow: 'IDENTITY_F' from os.environ.get (line 15, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · brand_manager.py (reported line 46)May include surrounding context.

python
def save_identity(data: dict):
    ensure_dirs()
    data["last_updated"] = date.today().isoformat()
    with open(IDENTITY_F, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)

Tainted flow: 'AUDIT_F' from os.environ.get (line 20, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · brand_manager.py (reported line 53)May include surrounding context.

python
def log_audit(message: str):
    ensure_dirs()
    ts = datetime.now().strftime("%Y-%m-%d %H:%M")
    with open(AUDIT_F, "a", encoding="utf-8") as f:
        f.write(f"\n[{ts}] {message}")

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module includes outbound Telegram messaging and consumes bot credentials, introducing a data egress capability beyond simple local brand-file management. In this skill context, remote notifications may be useful, but because they transmit user activity and identity-related content without prominent disclosure or explicit enablement, the capability increases risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

The hardcoded Telegram API endpoint confirms external transmission of command-generated data to a third-party service. In this skill's context, that is more dangerous because the advertised purpose is brand management, not remote telemetry, so users may not anticipate off-host data flow.

Content

Scanner excerpt · brand_manager.py (reported line 74)May include surrounding context.

python
import urllib.request, urllib.parse
        payload = json.dumps({"chat_id": chat_id, "text": message, "parse_mode": "Markdown"})
        req = urllib.request.Request(
            f"https://api.telegram.org/bot{token}/sendMessage",
            data=payload.encode(), headers={"Content-Type": "application/json"}
        )
        with urllib.request.urlopen(req, timeout=10):

Tainted flow: 'plat_dest' from os.environ.get (line 116, credential/environment) → shutil.copy (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · brand_manager.py (reported line 119)May include surrounding context.

python
plat_dest = f"{PLATFORMS_D}/config.json"
    if os.path.exists(plat_template) and not os.path.exists(plat_dest):
        import shutil
        shutil.copy(plat_template, plat_dest)

    # Copy voice guide template
    voice_template = os.path.join(TEMPLATE_DIR, "voice_guide.md")

Tainted flow: 'voice_dest' from os.environ.get (line 123, credential/environment) → shutil.copy (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · brand_manager.py (reported line 126)May include surrounding context.

python
voice_dest = f"{PLATFORMS_D}/voice_guide.md"
    if os.path.exists(voice_template) and not os.path.exists(voice_dest):
        import shutil
        shutil.copy(voice_template, voice_dest)

    # Initialize content queue
    queue_f = f"{CONTENT_D}/queue.json"

Tainted flow: 'queue_f' from os.environ.get (line 275, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · brand_manager.py (reported line 131)May include surrounding context.

python
# Initialize content queue
    queue_f = f"{CONTENT_D}/queue.json"
    if not os.path.exists(queue_f):
        with open(queue_f, "w") as f:
            json.dump({"queue": [], "generated": date.today().isoformat()}, f, indent=2)

    # Initialize network contacts

Tainted flow: 'queue_f' from os.environ.get (line 275, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · brand_manager.py (reported line 283)May include surrounding context.

python
# Initialize content queue
    queue_f = f"{CONTENT_D}/queue.json"
    if not os.path.exists(queue_f):
        with open(queue_f, "w") as f:
            json.dump({"queue": [], "generated": date.today().isoformat()}, f, indent=2)

    # Initialize network contacts

Tainted flow: 'contacts_f' from os.environ.get (line 449, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · brand_manager.py (reported line 137)May include surrounding context.

python
# Initialize network contacts
    contacts_f = f"{NETWORK_D}/contacts.json"
    if not os.path.exists(contacts_f):
        with open(contacts_f, "w") as f:
            json.dump({"contacts": [], "last_reviewed": date.today().isoformat()}, f, indent=2)

    log_audit("Brand identity initialized")

Tainted flow: 'contacts_f' from os.environ.get (line 449, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · brand_manager.py (reported line 466)May include surrounding context.

python
# Initialize network contacts
    contacts_f = f"{NETWORK_D}/contacts.json"
    if not os.path.exists(contacts_f):
        with open(contacts_f, "w") as f:
            json.dump({"contacts": [], "last_reviewed": date.today().isoformat()}, f, indent=2)

    log_audit("Brand identity initialized")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The morning-brief command sends schedule and branding activity data to Telegram without clear disclosure in the interface or module documentation. Undisclosed data sharing is risky because users may assume the command is local-only while business metadata is transmitted externally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The audit command transmits summarized business metrics such as revenue-proof counts, testimonials, and network status to Telegram without explicit user warning. Even aggregated metrics can leak sensitive operational insights to external systems or unintended recipients if the bot/chat configuration is wrong.

Content

No source excerpt is available for this finding.

Tainted flow: 'proof_file' from os.environ.get (line 409, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · brand_manager.py (reported line 418)May include surrounding context.

python
"file": proof_file,
    }

    with open(proof_file, "w") as f:
        json.dump(entry, f, indent=2)

    log_audit(f"Proof added: {proof_type} — {note}")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The evening review sends daily activity information externally without clear disclosure. In a personal-brand/business workflow, this can reveal behavioral patterns and progress information that users may reasonably expect to remain local.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This manifest-style JSON includes only a generic comment describing it as a platform configuration, but provides no explicit trigger scope, activation conditions, or exclusion examples. For manifest files, the absence of specific invocation constraints can make downstream skill activation behavior overly broad or unclear.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The README states that .learnings/LEARNINGS.md and AUDIT.md are 'Auto-populated by the skill', which implies file writes. However, the description does not include any explicit warning that the skill will modify or create files in the workspace, which is relevant user disclosure for a markdown skill description.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.