Back to skill

Security audit

golden-rule

Security checks for vulnerabilities and agentic risk

Overview

This Instagram automation is mostly disclosed, but it needs Review because it can post public replies and DMs from an account, uses a long-lived token, and runs an extra OpenClaw CLI notification.

Review this carefully before installing. Only use it if you intentionally want an agent to send Instagram DMs and public replies automatically from your business account. Use a least-privileged token, keep it out of source control, rotate it if exposed, and consider removing or disabling the OpenClaw webchat notification and replacing token query/payload use with safer authorization-header handling where supported.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
scripts/ig_golden_hour.py:1
Finding
Unpinned Runtime Dependency Creates Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ig_golden_hour.py`, lines 1-3 **Vulnerability Type**: Unrestricted third-party dependency resolution **Risk Level**: Medium ### Code Snippet ```python # /// script # dependencies = ["requests"] # /// ``` The documented invocation in `SKILL.md`, lines 20-25, causes `uv` to resolve this dependency at runtime: ```bash uv run {baseDir}/scripts/ig_golden_hour.py \ --media_id "12345678901234567" \ --keyword "bot" \ --dm_text "Here is the link you requested: https://example.com" \ --duration 60 ``` ### Technical Analysis The inline dependency declaration specifies `requests` without an exact version, lockfile, or integrity hash. Consequently, the package version installed by `uv run` can change over time without any corresponding change to the audited Skill. This does not establish that the current `requests` package is malicious. However, mutable dependency resolution creates a supply-chain exposure: a compromised upstream release, package repository, dependency, or package-resolution configuration could introduce code that was not included in the static audit. Imported Python packages execute inside the same process as the Skill. In this case, that process can access `IG_ACCESS_TOKEN`, `IG_ACCOUNT_ID`, command-line arguments, and the current user's filesystem and network privileges. ### Attack Path 1. An attacker compromises an upstream package release, transitive dependency, configured package index, or dependency-resolution environment. 2. The user invokes the documented `uv run` command. 3. `uv` resolves and installs the attacker-controlled or compromised package version because no audited version or hash is enforced. 4. The package executes during `import requests`. 5. Malicious initialization code reads Instagram credentials from the environment or performs other actions allowed by the local user. 6. The captured credentials may then be exfiltrated and used for unauthorized ...[truncated 648 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `requests` to a specifically reviewed version rather than using an unrestricted package name. 2. Create and commit a lockfile that records all transitive dependency versions. 3. Enforce package hashes or another integrity-verification mechanism during installation. 4. Resolve dependencies only from an explicitly configured, trusted package index. 5. Run automated dependency vulnerability and provenance checks in CI. 6. Execute the Skill in a restricted environment with access only to the credentials, files, and network destinations required for its operation. 7. Regularly review and deliberately update pinned dependencies rather than allowing implicit runtime upgrades. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ig_golden_hour.py:25
Finding
Instagram Access Token Exposed Through Request Parameters and Payloads<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ig_golden_hour.py`, lines 25-30 and 42-49 **Vulnerability Type**: Insecure bearer-token transmission and handling **Risk Level**: Medium ### Code Snippet ```python url = f"https://graph.facebook.com/v19.0/{media_id}/comments" params = { 'access_token': token, 'fields': 'id,text,from' } response = requests.get(url, params=params) comments = response.json().get('data', []) ``` The same access token is also embedded in outbound POST data: ```python payload = { "recipient": { "comment_id": c_id }, "message": { "text": dm_text }, "access_token": token } requests.post(f"https://graph.facebook.com/v19.0/me/messages", json=payload) # 2. Reply publicly to double the engagement print(f"💬 Replying publicly to the comment ID: {c_id}") payload_reply = { "message": "Just sent you a DM with the link! 🚀", "access_token": token } requests.post(f"https://graph.facebook.com/v19.0/{c_id}/replies", data=payload_reply) ``` ### Technical Analysis Sending authentication material to Meta is necessary for the declared Instagram automation. The security issue is the placement of the bearer token in request parameters rather than a dedicated authorization header. For the GET request, `requests` serializes `params` into the URL query string. Full URLs are commonly recorded by HTTP debugging tools, proxy logs, observability agents, exception reports, and network middleware. Although HTTPS protects the request in transit from ordinary passive observers, it does not prevent token retention by trusted endpoints, local instrumentation, TLS-terminating proxies, or diagnostic systems. The POST requests avoid placing the token in the URL but still mix authentication material into application payloads. This increases the possibility that request-body logging or debugging captures the credential. A dedicated authorization header provides clearer separation and allows standard secret-redaction controls to operate more re ...[truncated 1743 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use Meta's supported bearer-token authorization header where the relevant endpoint permits it: ```python headers = {"Authorization": f"Bearer {token}"} params = {"fields": "id,text,from"} response = requests.get(url, headers=headers, params=params, timeout=30) ``` 2. Apply the same authorization-header approach to POST requests where supported, keeping credentials out of JSON and form payloads. 3. Configure HTTP clients, proxies, monitoring systems, and exception collectors to redact `Authorization`, `access_token`, and equivalent sensitive fields. 4. Never enable verbose request logging in production while credentials are present. 5. Use a token with only the Graph API permissions and resource access required by this automation. 6. Store the token in a managed secret store or tightly controlled environment variable, and rotate it if exposure is suspected. 7. Add explicit connection and read timeouts and call `raise_for_status()` so authentication and API failures are handled predictably. 8. Avoid logging the full DM text because it may contain private content or sensitive links. ]]>
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (16)

Tainted flow: 'params' from os.environ.get (line 28, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
'access_token': token,
                'fields': 'id,text,from'
            }
            response = requests.get(url, params=params)
            comments = response.json().get('data', [])
            
            for comment in comments:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'payload' from os.environ.get (line 44, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
# 1. Send the Private DM Reply
                    print(f"📨 Sliding into DMs: {dm_text}")
                    payload = { "recipient": { "comment_id": c_id }, "message": { "text": dm_text }, "access_token": token }
                    requests.post(f"https://graph.facebook.com/v19.0/me/messages", json=payload)
                    
                    # 2. Reply publicly to double the engagement
                    print(f"💬 Replying publicly to the comment ID: {c_id}")
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'payload_reply' from os.environ.get (line 49, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
# 2. Reply publicly to double the engagement
                    print(f"💬 Replying publicly to the comment ID: {c_id}")
                    payload_reply = { "message": "Just sent you a DM with the link! 🚀", "access_token": token }
                    requests.post(f"https://graph.facebook.com/v19.0/{c_id}/replies", data=payload_reply)
                    
                    # 3. Notify Neo (OpenClaw)
                    try:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented purpose understates the actual behaviors: the skill appears to use local credentials, invoke shell commands, and send notifications to OpenClaw in addition to Instagram automation. This mismatch is dangerous because users and enforcement systems may approve the skill for one purpose while it performs additional side effects, including local command execution and third-party data disclosure.

Credential Access

High
Category
Privilege Escalation
Content
The user must have:
1. An Instagram Professional/Business account linked to a Facebook Page.
2. A Long-Lived Instagram Graph API Page Access Token (`IG_ACCESS_TOKEN`).
3. Their Instagram Business Account ID (`IG_ACCOUNT_ID`).

Ensure these are set in the environment or `.env` file before running the script.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Content
dencies = ["requests"]
# ///
import os
import time
import requests
import argparse

def golden_hour_monitor(media_id, keyword, dm_text, duration_minutes=60):
    token = os.environ.get("IG_ACCESS_TOKEN")
    account_id = os.environ.get("IG_ACCOUNT_ID")
    
    if not token or not account_id:
        print("🚨 Error: Missing IG_ACCESS_TOKEN or IG_ACCOUNT_ID.")
        return

    print(f"🕵️‍♂️ Starting Golden Hour Monitor on Post ID: {media_id}")
    print(f"🕒 Monitoring for exactly {duration_minutes} minutes.")
    print(f"🎯 Keyword Trigger: '{keyword}'")
    
    # Store replied comment IDs
    processed_comments = set()
    start_time = time.time()
    
    while (time.time() - start_time) < (duration_minutes * 60):
        try:
            url = f"https://graph.facebook.com/v19.0/{media_id}/comments"
            params = {
                'access_token': token,
                'fields': 'id,text,from'
            }
            response = requests.get(url, params=
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The skill executes an external CLI command unrelated to its stated Instagram monitoring and auto-reply purpose. Hidden or undocumented secondary actions are dangerous in agent skills because they create additional data flows and execution surfaces that users and reviewers did not consent to, and in this case they couple social-media activity to an external messaging channel.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Content
# 3. Notify Neo (OpenClaw)
                    try:
                        os.system(f"openclaw message send --target webchat --message '🚨 SUCCESS! I just sent the Mock Trading DM to an Instagram user who commented \"BOT\".'")
                    except:
                        pass
Confidence
95% confidence
Finding
The script invokes an external shell command via os.system to send an OpenClaw/webchat notification. Even though the command string is constant in this version, spawning a shell is unnecessary and expands the skill’s behavior beyond Instagram automation, creating command-execution risk and an unexpected side channel if the environment, PATH, or surrounding code is compromised.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill declares no explicit tool scope or permissions even though its documented behavior requires environment access, network access, and shell execution. In an agent setting, missing capability declarations weaken user consent and policy enforcement, making it easier for the skill to access credentials or perform actions outside what the user clearly authorized.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill description does not clearly warn that it will automatically post public replies and send direct messages on the user's behalf. That omission is risky because it can cause unintended impersonation, spam-like behavior, or account-policy violations if a user enables the skill without understanding the automated actions it will take.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill instructs users to place a long-lived Instagram access token in environment variables or a .env file without any handling or storage warning. Long-lived tokens can grant broad account access, so weak guidance increases the chance of accidental leakage through logs, source control, misconfigured hosts, or other local tooling.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The script polls the Facebook Graph API for comment data using fields that include comment text and sender information (`id,text,from`). While it prints that monitoring has started, it does not clearly disclose that user comment content and metadata will be fetched from Instagram/Facebook and processed continuously. This is a network operation involving user data, which falls under the missing-warning criteria for code files.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
Although the script logs each action at send time, it lacks an explicit advance disclosure that matching comments will trigger both a DM and a public reply. These are user-affecting outbound network actions, and the warning should be clear before execution rather than only when an individual message is sent.

External Transmission

Medium
Category
Data Exfiltration
Content
# 1. Send the Private DM Reply
                    print(f"📨 Sliding into DMs: {dm_text}")
                    payload = { "recipient": { "comment_id": c_id }, "message": { "text": dm_text }, "access_token": token }
                    requests.post(f"https://graph.facebook.com/v19.0/me/messages", json=payload)
                    
                    # 2. Reply publicly to double the engagement
                    print(f"💬 Replying publicly to the comment ID: {c_id}")
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The code sends external notifications to OpenClaw/webchat, but this behavior is not described in the skill metadata. Undisclosed outbound communications are a security and trust problem because they can leak operational events or user-related activity to another system without informed consent.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
Executing an external shell command without warning or explanation is risky because it introduces behavior outside the user’s expected workflow and outside the declared scope of the skill. In an agent-skill context, undisclosed execution is especially suspicious because it may be used to trigger side effects or covert notifications.

Static analysis

No suspicious patterns detected.