Back to skill

Security audit

fb_page_manager

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to perform its stated Facebook Page posting function, but it needs review because it handles powerful long-lived Meta credentials with weak storage guidance and broad posting triggers.

Install only if you are comfortable giving the skill authority to publish or schedule Facebook Page content. Use a dedicated Meta app and Page token with the narrowest permissions possible, avoid storing the token and app secret in shell profiles or shared config files, keep credential files private, and rotate the token if it may have been exposed. Confirm the target platform before approving any post.

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

T09 · Insecure Skill Coding Practices

Warning
Location
references/token-setup-guide.md:30
Finding
Sensitive Meta credentials are transmitted in query strings and stored in plaintext configuration<![CDATA[ ## Vulnerability Details **File Location**: `references/token-setup-guide.md:30-38`, with related plaintext storage instructions at `references/token-setup-guide.md:40-65` **Vulnerability Type**: Credential exposure through URL query parameters and persistent plaintext storage **Risk Level**: Medium ### Vulnerable Code Snippet ```text GET https://graph.facebook.com/v21.0/oauth/access_token?grant_type=fb_exchange_token&client_id={APP_ID}&client_secret={APP_SECRET}&fb_exchange_token={SHORT_LIVED_TOKEN} ``` ```text GET https://graph.facebook.com/v21.0/me/accounts?access_token={LONG_LIVED_USER_TOKEN} ``` The guide also directs users to persist credentials in shell configuration: ```bash export LONG_META_page_TOKEN="EAAxxxxxxx..." export META_PAGE_ID="123456789012345" export META_APP_SECRET="abcdef1234567890" ``` Alternatively, it recommends storing the same credentials in an OpenClaw JSON configuration: ```json { "skills": { "entries": { "fb-page-poster": { "enabled": true, "env": { "LONG_META_page_TOKEN": "EAAxxxxxxx...", "META_PAGE_ID": "123456789012345", "META_APP_SECRET": "abcdef1234567890" } } } } } ``` ### Technical Analysis The setup guide embeds an application secret and access tokens in URL query parameters. Query strings may be retained by browser history, command history, diagnostic tooling, HTTP client logs, reverse proxies, endpoint monitoring products, screenshots, or copied URLs. Although the documented destination is Meta's legitimate HTTPS Graph API, placing secrets in URLs unnecessarily increases the number of locations in which those secrets may persist. The guide also recommends long-term plaintext storage in a shell profile or `~/.openclaw/openclaw.json` without specifying restrictive file permissions or integration with a secret-management facility. A Page access token grants API access to the associated Facebook Page, while the application secret ...[truncated 1921 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace token-exchange examples that place secrets in URLs with POST requests that carry sensitive parameters in the request body. 2. Avoid workflows that require users to paste credential-bearing URLs into a browser address bar. 3. Use a secret manager, protected credential store, or OpenClaw-supported secure secret facility instead of ordinary plaintext configuration where available. 4. If file-based storage is unavoidable, require owner-only permissions, such as mode `0600`, and verify that parent directories are not accessible to other users. 5. Do not place secrets directly in shared shell profiles, version-controlled files, examples copied into repositories, or diagnostic output. 6. Add explicit guidance to exclude credential files from source control, backups with broad readership, support bundles, and logs. 7. Document immediate token invalidation and rotation procedures for suspected exposure. 8. Keep Page tokens and application secrets separated where practical so compromise of one storage location does not automatically disclose both. ]]>

T05 · Unauthorized Access and Privilege Escalation

Note
Location
references/token-setup-guide.md:20
Finding
The Skill requests a Page engagement permission that is not used by its implementation<![CDATA[ ## Vulnerability Details **File Location**: `references/token-setup-guide.md:20-25`; related requirement at `SKILL.md:16` **Vulnerability Type**: Excessive OAuth permission request **Risk Level**: Low ### Vulnerable Code Snippet The setup guide directs the user to grant three permissions: ```markdown ### Get a short-lived token 1. Open https://developers.facebook.com/tools/explorer/ 2. Select your app 3. Click **Generate Access Token** 4. Grant permissions: `pages_manage_posts`, `pages_read_engagement`, `pages_show_list` 5. Select your Page from the **Page Access Token** dropdown 6. Copy the token (valid ~1 hour) ``` The Skill documentation also identifies engagement-reading permission as a runtime requirement: ```markdown | `LONG_META_page_TOKEN` | Long-lived Page Access Token with `pages_manage_posts` and `pages_read_engagement` permissions | ``` ### Technical Analysis The implementation in `scripts/fb-post.js` performs only POST operations against Page feed, photo, and comment endpoints: ```javascript const r = await api(`/${PAGE_ID}/feed`, body); const r = await api(`/${PAGE_ID}/photos`, body); const r = await api(`/${postId}/comments`, { message: text }); ``` No code reads Page engagement data. Consequently, `pages_read_engagement` is not demonstrated as necessary for the declared capabilities of creating text posts, uploading images, scheduling posts, or adding a first comment. The `pages_manage_posts` permission is directly relevant to the publishing functionality. The `pages_show_list` permission may be needed during initial Page-token discovery through `/me/accounts`, but it should be treated as a setup-specific permission rather than an unqualified ongoing runtime requirement where Meta's token model permits narrower authorization. Requesting unused permissions violates the principle of least privilege. It does not itself bypass Meta's access controls, but it increases the information accessible if the token is later disclosed or ...[truncated 1153 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `pages_read_engagement` from the documented required permissions unless a concrete engagement-reading feature is implemented and documented. 2. Request only `pages_manage_posts` for the runtime posting workflow, subject to Meta's current endpoint requirements. 3. Treat `pages_show_list` as a setup-only permission used to discover the managed Page and obtain the appropriate Page token where the platform permits that separation. 4. Document the purpose of every requested OAuth permission and map each permission to the exact API operation that requires it. 5. Add a permission review whenever new functionality is introduced, and avoid expanding scopes preemptively. 6. Advise users to revoke and reauthorize existing tokens with the reduced permission set. 7. Test text posts, image posts, scheduled posts, and comments using the reduced token to confirm that no undocumented scope is operationally required. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Credential Access

High
Category
Privilege Escalation
Content
# Facebook Page Access Token Setup

## Prerequisites
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
| Symptom | Fix |
|---|---|
| Invalid OAuth access token | Re-generate token (Steps 2-3) |
| Requires pages_manage_posts | Re-authorize with correct permissions |
| Application does not have permission | Add yourself as tester in App Settings or switch to Live mode |
| Empty /me/accounts response | Re-authorize with `pages_show_list` |
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
*   node fb-post.js --type text --message "Post" --schedule "2025-12-25T10:00:00+0800"
 *
 * Env vars required:
 *   LONG_META_page_TOKEN  — Long-lived Page Access Token
 *   META_PAGE_ID          — Facebook Page ID
 *   META_APP_SECRET       — Meta App Secret (for appsecret_proof)
 */
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
*   node fb-post.js --type text --message "Post" --schedule "2025-12-25T10:00:00+0800"
 *
 * Env vars required:
 *   LONG_META_page_TOKEN  — Long-lived Page Access Token
 *   META_PAGE_ID          — Facebook Page ID
 *   META_APP_SECRET       — Meta App Secret (for appsecret_proof)
 */
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
*   node fb-post.js --type text --message "Post" --schedule "2025-12-25T10:00:00+0800"
 *
 * Env vars required:
 *   LONG_META_page_TOKEN  — Long-lived Page Access Token
 *   META_PAGE_ID          — Facebook Page ID
 *   META_APP_SECRET       — Meta App Secret (for appsecret_proof)
 */
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
*   node fb-post.js --type text --message "Post" --schedule "2025-12-25T10:00:00+0800"
 *
 * Env vars required:
 *   LONG_META_page_TOKEN  — Long-lived Page Access Token
 *   META_PAGE_ID          — Facebook Page ID
 *   META_APP_SECRET       — Meta App Secret (for appsecret_proof)
 */
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
*   node fb-post.js --type text --message "Post" --schedule "2025-12-25T10:00:00+0800"
 *
 * Env vars required:
 *   LONG_META_page_TOKEN  — Long-lived Page Access Token
 *   META_PAGE_ID          — Facebook Page ID
 *   META_APP_SECRET       — Meta App Secret (for appsecret_proof)
 */
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
*   node fb-post.js --type text --message "Post" --schedule "2025-12-25T10:00:00+0800"
 *
 * Env vars required:
 *   LONG_META_page_TOKEN  — Long-lived Page Access Token
 *   META_PAGE_ID          — Facebook Page ID
 *   META_APP_SECRET       — Meta App Secret (for appsecret_proof)
 */
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill declares access to environment variables and implicitly performs networked posting, but it does not declare any explicit tool scope or allowed-tools boundary. That makes the skill's operational privileges less transparent and can allow broader-than-expected execution in hosts that rely on manifest-declared permissions for enforcement or review.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are broad enough to match common conversational requests like 'post this' or 'publish this,' which can cause the skill to activate in ambiguous contexts. Because this skill performs external side effects by publishing to a social media page, accidental invocation could lead to unintended public posts or scheduling actions.

Session Persistence

Medium
Category
Rogue Agent
Content
## Step 1: Get your App Secret

1. Go to https://developers.facebook.com/apps/
2. Select your app (or create one with type **Business**)
3. Go to **Settings > Basic**
4. Copy the **App Secret** — this is your `META_APP_SECRET`
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The guide tells users to place a long-lived Page access token and the Meta App Secret into shell profiles or a local JSON config, but it does not warn that these are sensitive credentials or recommend secure secret storage. If these values are exposed through shell history, dotfile sync, backups, logs, screenshots, or accidental commits, an attacker could post to the Facebook Page or abuse the app credentials.

Static analysis

No suspicious patterns detected.