Back to skill

Security audit

Facebook Page Manager 1.0.0

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches Facebook Page management, but it also ships undisclosed X/Twitter-to-Facebook automation that can publish promotional content while handling powerful tokens in risky ways.

Review this carefully before installing. Use only in an isolated environment with test Pages unless you remove or disable the X/Twitter digest scripts, verify any bird executable, avoid broad environment variables, and store Meta/X credentials in a protected secret store. Do not run delete, hide, reply, or digest-post commands unless you have reviewed the exact target and final public content.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (6)

T01 · Skill Instruction Hijacking

Error
Location
scripts/x_digest_to_fb.js:139
Finding

Undeclared promotional content is automatically inserted into Facebook posts

Content
View full analysis
{ const author = t.author?.username ? `@${t.author.username}` : ""; const text = (t.text || "").replace(/\s+/g, " ").trim(); const snippet = text.length > 160 ? text.slice(0, 157) + "…" : text; lines.push(`${i + 1}) ${author}: ${snippet}`); lines.push(` ${tweetUrl(t)}`); }); lines.push(""); lines.push("Theo dõi thêm: clawd.bot | github.com/clawdbot/clawdbot"); lines.push("#Clawdbot #Moltbot #AI #Automation #OpenSource"); return lines.join("\n").slice(0, 6000); } ``` The resulting caption is published immediately: ```js const caption = buildCaption(top); let result; if (photoUrl) { const imgPath = await downloadToTmp(photoUrl); result = await fbUploadPhoto(pageId, pageInfo.token, imgPath, caption); } else { const url = new URL(`${FB_BASE}/${pageId}/feed`); url.searchParams.set("access_token", pageInfo.token); const body = new URLSearchParams({ message: caption }); const resp = await fetch(url, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body, }); const data = await resp.json(); if (!resp.ok) throw new Error(`FB error: ${JSON.stringify(data)}`); result = data; } ``` ### Technical Ana ...[truncated 1365 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/x_digest_collect.js:22
Finding

X session credentials and the complete process environment are exposed to an unverified PATH executable

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/x_digest_to_fb.js:112
Finding

Untrusted image URLs are fetched and republished without destination, type, or size validation

Content
View full analysis
t.media?.some((m) => m.type === "photo" && m.url)); const photoUrl = withPhoto?.media?.find((m) => m.type === "photo" && m.url)?.url; const caption = buildCaption(top); let result; if (photoUrl) { const imgPath = await downloadToTmp(photoUrl); result = await fbUploadPhoto(pageId, pageInfo.token, imgPath, caption); } ``` ### Technical Analysis The media URL comes from JSON returned by the external `bird` executable. The code does not validate the URL scheme, hostname, resolved address, redirect destinations, response MIME type, or response size. `response.arrayBuffer()` buffers the complete response in memory before writing it to disk. A large response can therefore cause memory exhaustion, followed by disk consumption. Because the resulting file is uploaded as an image to Facebook without decoding or verifying it, data obtained from an internal endpoint could also be transmitted to Facebook. ### Attack Path 1. An attacker controls or manipulates the `bird` output, or causes a selected result to contain a malicious media URL. 2. The URL points to a loopback service, private network address, link-local metadata servi ...[truncated 764 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/auth.js:63
Finding

Meta application secrets and access tokens are transmitted in URL query strings

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/auth.js:14
Finding

Long-lived Meta tokens are stored in the project directory with a non-atomic permission change

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/cli.js:246
Finding

Page comment operations use a broader user token without binding targets to a selected Page

Content
View full analysis
", "Post ID") .option("--limit ", "Number of comments", "25") .action(async (opts) => { const tokens = loadTokens(); const userToken = tokens.user_token; const result = await apiGet(`${opts.post}/comments`, userToken, { fields: "id,message,from,created_time,like_count,is_hidden", limit: opts.limit, }); ``` Comment modification also uses the user token without requiring a Page ID: ```js commentsCmd .command("hide") .description("Hide a comment") .requiredOption("--comment ", "Comment ID") .action(async (opts) => { const tokens = loadTokens(); const userToken = tokens.user_token; const result = await apiPost(opts.comment, userToken, { is_hidden: "true" }); if (result.success) { console.log("Comment hidden successfully"); } else { console.log("Failed to hide comment"); } }); ``` The same token-selection pattern is used for reply, unhide, and delete operations. ### Technical Analysis The project stores Page-specific tokens and already provides `getPageToken()` for Page operations, but comment commands instead use the broader user token. They accept only a post or comment ID and do not require a Page ID or verify that the target object belongs to an explicitly selected Page. This exceeds the minimum authorization context needed for an operation tied to one Facebook Page and weakens the local boundary between Pages represented in the token file. The implementation also conflicts with the bundled API reference, which describes Page tokens as the credentials used for Page-specific operations. In addition, `SKIL ...[truncated 978 chars]
Remediation
View remediation
` for every comment operation. - Resolve the corresponding Page token with `getPageToken()` and use it instead of the user token. - Verify that the supplied post or comment belongs to the selected Page before performing a modifying request. - Request `pages_manage_engagement` only when comment-management functionality is enabled and clearly explain why it is needed. - Separate read-only and management authorization flows where practical. - Avoid retaining the broad user token after Page tokens have been obtained unless a documented refresh operation requires it. - Add tests proving that a token for one Page cannot be used through the CLI to act on another Page. ]]>
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (33)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code chunk implements a narrow posting utility, not a full Facebook Page management skill. Its actual behavior is limited to reading a page token from tokens.json, reading caption text from a file, and creating either a text post or photo post through the Graph API. There is no code for retrieving Page posts, listing comments, replying to comments, hiding comments, deleting comments, or explicitly posting link content. Because the declared description claims broader management capabilities that are not present in the supplied code, the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description says this skill manages Facebook Pages through the Meta Graph API for posting, listing posts, and managing comments. The supplied code does none of that. Instead, it searches X/Twitter for terms like 'clawdbot' and 'moltbot', scores and filters matching tweets, outputs a JSON digest, and downloads an image from a selected tweet to /tmp. This is a materially different primary purpose, uses different services and credentials, and includes unrelated functionality. Therefore the description does not accurately represent the code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description presents a general-purpose Facebook Page management skill: posting content, listing posts, and handling comments. The code instead performs a specialized automation pipeline that pulls data from X/Twitter, scores and selects tweets about specific topics/authors, optionally downloads an image from X content, and republishes a digest to a Facebook Page. That cross-platform content ingestion from X is a significant undeclared capability and the primary purpose is materially narrower and different from the declared Facebook management role. While it does post to Facebook via the Graph API, it does not implement the declared list-posts or comment management behaviors in this code chunk.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
82% confidence
Finding

The skill instructs users to place a Meta App Secret in a local .env file to support a manual OAuth flow. For a skill that also stores long-lived and page tokens locally, this increases the chance of credential leakage through accidental commits, backups, permissive file permissions, or reuse of secrets across environments; compromise would grant powerful access to page management functions.

Content

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

bash
cd skills/facebook-page
cp .env.example .env
# Edit .env với App ID và Secret

4. Cài dependencies và lấy token

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 30)May include surrounding context.

md
# Facebook Page Skill Configuration
# Copy this file to .env and fill in your values

# Meta App credentials (from developers.facebook.com)
META_APP_ID=your_app_id_here

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 33)May include surrounding context.

md
# Facebook Page Skill Configuration
# Copy this file to .env and fill in your values

# Meta App credentials (from developers.facebook.com)
META_APP_ID=your_app_id_here

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 · env_example.md (reported line 2)May include surrounding context.

md
# Facebook Page Skill Configuration
# Copy this file to .env and fill in your values

# Meta App credentials (from developers.facebook.com)
META_APP_ID=your_app_id_here

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 · scripts/auth.js (reported line 18)May include surrounding context.

js
# Facebook Page Skill Configuration
# Copy this file to .env and fill in your values

# Meta App credentials (from developers.facebook.com)
META_APP_ID=your_app_id_here

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 · scripts/auth.js (reported line 37)May include surrounding context.

js
# Facebook Page Skill Configuration
# Copy this file to .env and fill in your values

# Meta App credentials (from developers.facebook.com)
META_APP_ID=your_app_id_here

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 · scripts/cli.js (reported line 19)May include surrounding context.

js
# Facebook Page Skill Configuration
# Copy this file to .env and fill in your values

# Meta App credentials (from developers.facebook.com)
META_APP_ID=your_app_id_here

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
94% confidence
Finding

The documented DELETE /{post-id} operation is a destructive capability that can be abused if an agent is induced to act on attacker-supplied or misidentified post IDs. In the context of a skill that manages live Facebook Pages, parameter misuse or insufficient confirmation can directly remove public content from production assets.

Content

Scanner excerpt · references/graph-api.md (reported line 60)May include surrounding context.

Delete post

text
DELETE /{post-id}

Comments

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
94% confidence
Finding

The documented DELETE /{comment-id} operation can be exploited through attacker-controlled identifiers or ambiguous intent, causing unauthorized removal of user-generated content. Because the skill is intended for comment moderation on live Pages, the context makes this more dangerous: mistakes or abuse can affect public interactions, moderation integrity, and user trust immediately.

Content

Scanner excerpt · references/graph-api.md (reported line 86)May include surrounding context.

Delete comment

text
DELETE /{comment-id}

Permissions

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 · scripts/auth.js (reported line 15)May include surrounding context.

js
const __dirname = dirname(fileURLToPath(import.meta.url));
const SKILL_DIR = join(__dirname, "..");
const ENV_FILE = join(SKILL_DIR, ".env");
const TOKENS_FILE = join(SKILL_DIR, "tokens.json");

// Load .env from skill directory

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 · scripts/cli.js (reported line 16)May include surrounding context.

js
const __dirname = dirname(fileURLToPath(import.meta.url));
const SKILL_DIR = join(__dirname, "..");
const ENV_FILE = join(SKILL_DIR, ".env");
const TOKENS_FILE = join(SKILL_DIR, "tokens.json");

// Load .env from skill directory

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file is clearly unrelated to the declared Facebook Page management skill: it searches X/Twitter content, processes tweets, and downloads tweet images. In a skill ecosystem, such scope mismatch is dangerous because it introduces undeclared data access and network behavior, making review, consent, and least-privilege enforcement ineffective.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script invokes an external 'bird' tool to query X/Twitter and explicitly requires X authentication secrets (AUTH_TOKEN, CT0), none of which are justified by a Facebook-only skill. This creates hidden credential and network-access scope that could expose unrelated secrets, perform unauthorized external actions, or evade user expectations about what the skill can access.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill declares network and environment-dependent behavior but does not define an explicit tool scope such as allowed-tools or permissions. That omission weakens reviewability and can lead to broader-than-expected access at runtime, especially for a skill that handles OAuth flows, tokens, and external API calls.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file presents the skill instructions and operational guidance in Vietnamese, which effectively forces a specific language for users reading the documentation. The policy allows locale constraints only when users are given a choice or the restriction is clearly documented and justified, neither of which appears here.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

The documentation directs users to obtain long-lived user tokens and then page tokens, and later states that page tokens do not expire and are saved to a local tokens.json path. Persisting long-lived session material on disk increases the blast radius of local compromise because stolen tokens can enable continued access to Facebook Page content and comment/post management without reauthentication.

Content

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

md
## Setup (một lần)

### 1. Tạo Meta App
1. Vào https://developers.facebook.com/apps/ → Create App
2. Chọn **"Other"** → **"Business"** (hoặc Consumer tuỳ use-case)
3. Điền tên app, email
4. Vào **App settings > Basic**: lấy **App ID** và **App Secret**

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The authentication section explains how to obtain and use access tokens, including page access tokens, but provides no guidance on treating them as secrets. Because these tokens authorize posting, deleting content, and managing engagement, poor handling could lead to account takeover of Page operations or unauthorized API actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The reference includes destructive operations such as deleting posts/comments and hiding comments without any caution about irreversible impact, confirmation requirements, or production-safety guidance. In a skill designed to manage live Facebook Pages, this increases the chance that an agent or user triggers content-destructive actions unintentionally or without understanding the consequences.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest says the skill can manage comments, including listing, replying, hiding, and deleting comments. However, this auth script only requests pages_show_list, pages_read_engagement, pages_manage_posts, and public_profile, with no scopes corresponding to the claimed comment-moderation capabilities, so the implemented behavior does not match the advertised scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script stores OAuth user and page access tokens to a local JSON file without prominently warning the operator beforehand. Even though file permissions are tightened to 0600, local credential persistence increases exposure to accidental backup leakage, developer mishandling, or compromise of the host account.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file header openly states that it collects candidate tweets for a digest, which directly contradicts the skill's claimed Facebook Page purpose. This kind of declared-intent mismatch is a strong indicator of repurposed or improperly bundled code, reducing trust in the package and increasing the chance of hidden or unauthorized capabilities.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script fetches remote media URLs and writes the contents to local disk under /tmp, behavior outside the stated Facebook Page management scope. Even without obvious code execution, undeclared downloading can be abused for SSRF-like access patterns, storage abuse, ingestion of untrusted content, or staging data for later exfiltration by other components.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.exposed_secret_literal (+1 more)

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/x_digest_collect.js:20

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/auth.js:32

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/x_digest_collect.js:14

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/x_digest_to_fb.js:27

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/auth.js:69

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
scripts/auth.js:53

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
scripts/cli.js:31

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
scripts/fb_post.js:66

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
scripts/x_digest_to_fb.js:36