Back to skill

Security audit

Instagram Page

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Instagram Business API helper, but users should handle its local token file and setup-only app secret carefully.

Install only if you are comfortable giving an agent the Instagram permissions you grant to the Meta token, including publishing and comment-management permissions if enabled. Store only IG_ACCESS_TOKEN and IG_USER_ID after setup, delete IG_APP_SECRET immediately, restrict credentials.json to your user account, avoid logging full request URLs, and rotate the token if the file may have been exposed.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:54
Finding
Unnecessary Persistence of the Meta App Secret with Delayed Permission Hardening<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 54-67 **Vulnerability Type**: Unnecessary plaintext secret persistence and non-atomic access-control hardening **Risk Level**: Medium ### Complete Code Snippet ```powershell # 3. Save - only these four fields @{ IG_USER_ID = $igUserId IG_ACCESS_TOKEN = $longToken IG_APP_ID = $appId IG_APP_SECRET = $appSecret } | ConvertTo-Json | Set-Content "$HOME/.config/instagram-page/credentials.json" -Encoding UTF8 ``` ```powershell # Windows icacls "$HOME/.config/instagram-page/credentials.json" /inheritance:r /grant:r "$($env:USERNAME):(R,W)" # macOS / Linux # chmod 600 ~/.config/instagram-page/credentials.json ``` The associated metadata also declares the sensitive credential file and optional app-secret field at `_meta.json`, lines 18-45. ### Technical Analysis The setup procedure writes `IG_APP_SECRET` to the persistent runtime credential file even though the Skill explicitly states that this value is needed only during the one-time token exchange. Routine API operations require only `IG_ACCESS_TOKEN` and `IG_USER_ID`, so persisting the app secret exceeds the minimum credential set necessary for runtime operation. The file is created before its permissions are restricted. Permission hardening is performed as a separate command, which creates an exposure window if the command is delayed, omitted, or fails. On macOS and Linux, the supplied `chmod` command is commented out and therefore is not executed as part of the shown setup block. The metadata correctly marks the file as sensitive and the app secret as optional, but it does not mitigate the unsafe persistence instruction in `SKILL.md`. ### Attack Path 1. A user follows the documented token-exchange procedure. 2. PowerShell writes the long-lived access token and Meta app secret to `~/.config/instagram-page/credentials.json`. 3. The file initially receives permissions according to the platform and environmen ...[truncated 1065 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never persist `IG_APP_SECRET` or `IG_APP_ID` in the runtime credential file. Save only the values required during normal operation: ```powershell @{ IG_USER_ID = $igUserId IG_ACCESS_TOKEN = $longToken } | ConvertTo-Json ``` 2. Create the credential directory and file with restrictive permissions before or atomically with writing sensitive data. 3. On macOS and Linux, set a restrictive `umask`, create the file with owner-only access, and verify that its final mode is `0600`. 4. On Windows, create or preconfigure the file with inheritance disabled and access limited to the current user before storing credentials. 5. Check command exit status and inspect the resulting ACL or file mode. Abort setup if restrictive permissions cannot be established. 6. Keep the app secret only in a temporary in-memory variable during exchange, clear it afterward, and avoid writing it to logs or command output. 7. Update `_meta.json` so the primary runtime credential schema contains only `IG_ACCESS_TOKEN` and `IG_USER_ID`; document setup-only values separately. 8. Rotate the app secret and access token if they were previously stored in a file with uncertain permissions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:46
Finding
Long-Lived Access Tokens Embedded in Request URLs<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 46-49, 75, 118, 129, and 149 **Vulnerability Type**: Credential exposure through URL query parameters **Risk Level**: Medium ### Complete Code Snippets ```powershell $r1 = Invoke-RestMethod "https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=$appId&client_secret=$appSecret&fb_exchange_token=$shortToken" $longToken = $r1.access_token # 2. Get Instagram Business Account ID linked to your Facebook Page $r2 = Invoke-RestMethod "https://graph.facebook.com/v25.0/$fbPageId?fields=instagram_business_account&access_token=$longToken" ``` ```powershell $r = Invoke-RestMethod "https://graph.facebook.com/oauth/access_token?grant_type=ig_refresh_token&access_token=$token" ``` ```powershell $result = Invoke-RestMethod -Uri "https://graph.facebook.com/v25.0/ENDPOINT?access_token=$token" -ErrorAction Stop ``` ```powershell $result = Invoke-RestMethod -Uri "https://graph.facebook.com/v25.0/{id}?access_token=$token" -Method DELETE -ErrorAction Stop ``` ```powershell $status = Invoke-RestMethod "https://graph.facebook.com/v25.0/$($container.id)?fields=status_code&access_token=$token" ``` ### Technical Analysis The Skill places the app secret, short-lived token, and long-lived access token directly in URL query strings. HTTPS protects the request in transit against ordinary passive network observation, but it does not prevent complete URLs from being captured by local diagnostics, HTTP client telemetry, exception records, debugging output, authorized proxies, or other URL-logging infrastructure. The exposure is especially significant because the document describes the access token as long-lived and directs users to grant permissions that may include content publishing, comment management, and insights access. The practice is repeated across setup, token refresh, GET, DELETE, and asynchronous status-polling requests. POST publishing examples generally place the acces ...[truncated 1360 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use Meta-supported authorization headers instead of URL query parameters wherever the relevant endpoint supports them. 2. For endpoints that support request bodies, transmit credentials in the body rather than embedding them in the URI. 3. Avoid constructing, displaying, or recording complete credential-bearing URLs. 4. Add explicit token and app-secret redaction to exception handling, diagnostics, and HTTP tracing. 5. Disable verbose request logging in production or configure it to strip query strings and authorization data. 6. If an endpoint strictly requires a query parameter, document the residual risk and ensure that proxies, telemetry, command transcripts, and diagnostic systems redact that parameter. 7. Rotate any token or app secret that may already have appeared in retained logs. 8. Add a review rule or automated scan that rejects examples containing `access_token=`, `client_secret=`, or temporary exchange tokens in URLs. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (14)

Credential Access

High
Category
Privilege Escalation
Content
---
name: instagram-page
description: "Instagram Business manager: post photos, reels, stories & get insights. Requires: powershell/pwsh. Reads ~/.config/instagram-page/credentials.json (IG_ACCESS_TOKEN, IG_USER_ID). IG_APP_SECRET for one-time setup only — delete afterward. Token expires every 60 days — refresh before expiry. Grant minimal permissions only. No data forwarded to third parties; all calls go to graph.facebook.com only."
metadata: {"openclaw":{"emoji":"[ig]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
---
name: instagram-page
description: "Instagram Business manager: post photos, reels, stories & get insights. Requires: powershell/pwsh. Reads ~/.config/instagram-page/credentials.json (IG_ACCESS_TOKEN, IG_USER_ID). IG_APP_SECRET for one-time setup only — delete afterward. Token expires every 60 days — refresh before expiry. Grant minimal permissions only. No data forwarded to third parties; all calls go to graph.facebook.com only."
metadata: {"openclaw":{"emoji":"[ig]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
---
name: instagram-page
description: "Instagram Business manager: post photos, reels, stories & get insights. Requires: powershell/pwsh. Reads ~/.config/instagram-page/credentials.json (IG_ACCESS_TOKEN, IG_USER_ID). IG_APP_SECRET for one-time setup only — delete afterward. Token expires every 60 days — refresh before expiry. Grant minimal permissions only. No data forwarded to third parties; all calls go to graph.facebook.com only."
metadata: {"openclaw":{"emoji":"[ig]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
---
name: instagram-page
description: "Instagram Business manager: post photos, reels, stories & get insights. Requires: powershell/pwsh. Reads ~/.config/instagram-page/credentials.json (IG_ACCESS_TOKEN, IG_USER_ID). IG_APP_SECRET for one-time setup only — delete afterward. Token expires every 60 days — refresh before expiry. Grant minimal permissions only. No data forwarded to third parties; all calls go to graph.facebook.com only."
metadata: {"openclaw":{"emoji":"[ig]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
---
name: instagram-page
description: "Instagram Business manager: post photos, reels, stories & get insights. Requires: powershell/pwsh. Reads ~/.config/instagram-page/credentials.json (IG_ACCESS_TOKEN, IG_USER_ID). IG_APP_SECRET for one-time setup only — delete afterward. Token expires every 60 days — refresh before expiry. Grant minimal permissions only. No data forwarded to third parties; all calls go to graph.facebook.com only."
metadata: {"openclaw":{"emoji":"[ig]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
---
name: instagram-page
description: "Instagram Business manager: post photos, reels, stories & get insights. Requires: powershell/pwsh. Reads ~/.config/instagram-page/credentials.json (IG_ACCESS_TOKEN, IG_USER_ID). IG_APP_SECRET for one-time setup only — delete afterward. Token expires every 60 days — refresh before expiry. Grant minimal permissions only. No data forwarded to third parties; all calls go to graph.facebook.com only."
metadata: {"openclaw":{"emoji":"[ig]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
---
name: instagram-page
description: "Instagram Business manager: post photos, reels, stories & get insights. Requires: powershell/pwsh. Reads ~/.config/instagram-page/credentials.json (IG_ACCESS_TOKEN, IG_USER_ID). IG_APP_SECRET for one-time setup only — delete afterward. Token expires every 60 days — refresh before expiry. Grant minimal permissions only. No data forwarded to third parties; all calls go to graph.facebook.com only."
metadata: {"openclaw":{"emoji":"[ig]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
---
name: instagram-page
description: "Instagram Business manager: post photos, reels, stories & get insights. Requires: powershell/pwsh. Reads ~/.config/instagram-page/credentials.json (IG_ACCESS_TOKEN, IG_USER_ID). IG_APP_SECRET for one-time setup only — delete afterward. Token expires every 60 days — refresh before expiry. Grant minimal permissions only. No data forwarded to third parties; all calls go to graph.facebook.com only."
metadata: {"openclaw":{"emoji":"[ig]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
---
name: instagram-page
description: "Instagram Business manager: post photos, reels, stories & get insights. Requires: powershell/pwsh. Reads ~/.config/instagram-page/credentials.json (IG_ACCESS_TOKEN, IG_USER_ID). IG_APP_SECRET for one-time setup only — delete afterward. Token expires every 60 days — refresh before expiry. Grant minimal permissions only. No data forwarded to third parties; all calls go to graph.facebook.com only."
metadata: {"openclaw":{"emoji":"[ig]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
---
name: instagram-page
description: "Instagram Business manager: post photos, reels, stories & get insights. Requires: powershell/pwsh. Reads ~/.config/instagram-page/credentials.json (IG_ACCESS_TOKEN, IG_USER_ID). IG_APP_SECRET for one-time setup only — delete afterward. Token expires every 60 days — refresh before expiry. Grant minimal permissions only. No data forwarded to third parties; all calls go to graph.facebook.com only."
metadata: {"openclaw":{"emoji":"[ig]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Field | Purpose |
|---|---|
| `IG_ACCESS_TOKEN` | Long-lived User access token - used for all API calls |
| `IG_USER_ID` | Instagram-scoped Business/Creator User ID (numeric) |
| `IG_APP_ID` | Meta App ID - only needed during token exchange |
| `IG_APP_SECRET` | Meta App Secret - only needed during token exchange |
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
IG_ACCESS_TOKEN = $longToken
    IG_APP_ID       = $appId
    IG_APP_SECRET   = $appSecret
} | ConvertTo-Json | Set-Content "$HOME/.config/instagram-page/credentials.json" -Encoding UTF8
```

**Restrict file permissions immediately after saving:**
Confidence
92% confidence
Finding
The skill instructs saving IG_APP_SECRET alongside the long-lived access token in a plain JSON file on disk. Even though it says the app secret is only for one-time setup, persisting it materially increases secret exposure risk if the workstation, backups, logs, or repository are compromised.

Credential Access

High
Category
Privilege Escalation
Content
```powershell
$r = Invoke-RestMethod "https://graph.facebook.com/oauth/access_token?grant_type=ig_refresh_token&access_token=$token"
$cfg.IG_ACCESS_TOKEN = $r.access_token
$cfg | ConvertTo-Json | Set-Content "$HOME/.config/instagram-page/credentials.json" -Encoding UTF8
```

> **Delete IG_APP_SECRET** from credentials.json after setup - it is not needed for API calls.
Confidence
78% confidence
Finding
The refresh flow writes the updated token back to an unencrypted local JSON file, continuing a pattern of long-lived credential storage on disk. While common in CLI tooling, this remains a real exposure point because token theft would allow API actions as the account until expiry or revocation.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# Windows
icacls "$HOME/.config/instagram-page/credentials.json" /inheritance:r /grant:r "$($env:USERNAME):(R,W)"
# macOS / Linux
# chmod 600 ~/.config/instagram-page/credentials.json
```

**Refresh token before it expires (every ~50 days):**
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Static analysis

No suspicious patterns detected.