Back to skill

Security audit

Follow Builders Sidecar

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its stated digest sidecar purpose, but it handles reusable Feishu credentials with under-scoped network and local-file safeguards.

Review before installing. Use only trusted Feishu accounts, avoid direct_credentials unless necessary, do not configure custom Feishu domains, and check permissions on ~/.follow-builders-sidecar if you proceed. The publisher should restrict Feishu domains to feishu/lark, store credentials with 0600-style protections, and replace predictable /tmp files with private per-run temporary directories.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • 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 (4)

T01 · Skill Instruction Hijacking

Note
Location
prompts/digest-intro.md:58
Finding

Mandatory Promotional Content Injected into Generated Digests

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/feishu-card-api.js:20
Finding

Arbitrary Feishu API Base URL Can Receive Application Secrets and Bearer Tokens

Content
View full analysis
{}) { const apiBase = resolveApiBase(creds.domain); log('info', 'Requesting Feishu tenant token', { accountId: creds.accountId }); const payload = await fetchJson(`${apiBase}/auth/v3/tenant_access_token/internal`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ app_id: creds.appId, app_secret: creds.appSecret }) }); if (payload?.code !== 0 || !payload?.tenant_access_token) { throw new Error(`Failed to get Feishu tenant token: ${payload?.msg || 'unknown error'}`); } log('info', 'Feishu tenant token acquired', { accountId: creds.accountId }); return payload.tenant_access_token; } ``` The same computed API base is subsequently used with the tenant token: ```javascript const response = await fetch(`${apiBase}/im/v1/images`, { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body: form }); ``` ```javascript const payload = await fetchJson( `${apiBase}/im/v1/messages?receive_id_type=${encodeURIComponent(receiveIdType)}`, { method: 'POST', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ receive_id: target, msg_type: 'interactive', content: JSON.stringify(card) }) } ); ``` ### Technical Analysis Although the documented `domain` values are `feish ...[truncated 2093 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/sidecar-credentials.js:37
Finding

Feishu Application Secret Is Stored Without Explicit Restrictive Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run-sidecar.js:43
Finding

Predictable Shared Temporary Files Permit Symlink Attacks and Payload Tampering

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (58)

Credential Access

High
Category
Privilege Escalation
Confidence
87% confidence
Finding

The README explicitly describes writing plaintext appId, appSecret, and chatId into a local file under the user's home directory. If local filesystem access is obtained by another user, process, backup system, or malware, these credentials can be harvested and used to access or abuse the Feishu integration.

Content

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

md
Feishu card delivery supports two modes:

- `openclaw_account`: reuse an OpenClaw-configured Feishu account plus a target chat id
- `direct_credentials`: write a local-only Feishu `appId` / `appSecret` / `chatId` into `~/.follow-builders-sidecar/credentials.json`

If the chosen Feishu app cannot upload images, avatar upload falls back to the
configured default OpenClaw Feishu account.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about operational control of scheduling and digest delivery for another skill, including takeover/rollback behavior. The supplied code does none of that. Instead, it is an image utility that processes avatar files using Pillow. This is a materially different primary purpose and introduces undeclared file/image-processing capabilities unrelated to the stated sidecar functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about scheduling/delivery takeover and rollback behavior for a sidecar around the follow-builders skill. The supplied code does not implement scheduling, cron takeover, digest configuration, status inspection, or rollback. Instead, it is a standalone integration module for Feishu/Lark messaging that authenticates to Feishu, retrieves avatar images from external URLs, uploads images, and sends interactive cards. Those are materially different capabilities and resources from the declared purpose, so this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is about operational control of scheduling and delivery takeover for a follow-builders skill, including configuration, status inspection, and rollback behavior. The supplied code does not implement scheduling, cron takeover, digest configuration, status inspection, or rollback logic. Instead, it provides helper functions for a Feishu card/local messaging workflow: parsing CLI args such as recipient/account info, reading JSON from file/stdin, generating temporary files, calling a Python image-cropping script for avatars, and writing card JSON. These are materially different capabilities and indicate a different primary purpose than the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description is about a sidecar that manages scheduling and delivery takeover behavior for another skill, including status inspection and rollback to original cron. The supplied code does not implement scheduling, delivery orchestration, takeover state inspection, or rollback. Instead, it only reads configuration and source data from disk and loads prompt files, optionally fetching prompt text remotely. Those behaviors are not aligned with the stated primary purpose. While config loading could be a supporting detail, the chunk’s main functionality is generic resource loading, and the remote prompt fetch is an undeclared capability not suggested by the description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is about orchestration and operational control of a sidecar skill: taking over scheduling and delivery, configuring digest delivery, checking takeover status, and rolling back cron behavior. The supplied code does not implement any of those control-plane functions. Instead, it implements content/network utility functions for retrieving and parsing remote data from podcast RSS endpoints and Twitter/X oEmbed APIs. These are materially different capabilities and resources than the description suggests, so this chunk does not accurately represent the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description focuses on scheduling/delivery takeover management for an upstream skill: configuring delivery, inspecting takeover status, and rolling back cron behavior. The supplied code does not implement takeover management, scheduling control, status inspection, rollback, or cron-related behavior. Instead, it prepares content for digest generation by reading config, downloading feed data and prompt files, enriching content, and printing a JSON payload. This is a materially different primary purpose and includes undeclared network/content aggregation capabilities, so the description does not accurately represent the code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description centers on operational sidecar behavior for scheduling and delivery management of another skill. The supplied code chunk does not implement any of those functions. Instead, it is a pure rendering utility that parses a JSON file and converts digest content into formatted plaintext. It has no cron interaction, no status inspection, no delivery/channel configuration, and no takeover/rollback mechanisms. This is a materially different primary purpose, so the description does not accurately represent the code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is about a sidecar that manages operational takeover of scheduling and delivery for another skill: taking over cron/scheduling, configuring delivery, checking takeover status, and rolling back. The supplied code does not implement those control-plane behaviors. Instead, it is a content-processing and delivery pipeline for generating a daily AI builders digest as a Feishu card. Its primary function is to assemble source data, filter relevant items, prompt an LLM to create structured card content, normalize/repair the result, persist a payload file, and optionally send the card. While 'delivery' is partially involved via optional Feishu sending, the scheduling/takeover/status/rollback aspects central to the declared purpose are absent. Therefore the code materially differs from the declared purpose and includes undeclared content-generation and source-processing capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about an OpenClaw sidecar that manages takeover of scheduling and delivery for another skill, including status inspection and rollback to the original cron. The supplied code chunk does not implement scheduling control, cron takeover, rollback, or status inspection. Instead, it is a delivery utility focused specifically on composing and sending Feishu cards from supplied content. While 'delivery' is mentioned in the description, this code's concrete primary purpose is message construction and transmission via Feishu APIs, including credential resolution, avatar fetching/uploading, and recipient targeting—capabilities not reflected in the declared description. This is therefore a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The skill reads an existing local config, can reuse configured delivery accounts, and optionally writes direct Feishu app credentials to a local credentials.json file. Handling reusable messaging credentials materially raises the risk of account compromise, unauthorized message sending, or credential leakage if storage permissions, redaction, and lifecycle controls are weak.

Content

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

md
- reads `~/.follow-builders/config.json` once during takeover
- writes `~/.follow-builders-sidecar/config.json`
- writes `~/.follow-builders-sidecar/state.json`
- optionally writes `~/.follow-builders-sidecar/credentials.json` for local-only direct Feishu app credentials
- can reuse OpenClaw-configured Feishu account settings when Feishu card delivery is enabled

## When to use this skill

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/sidecar-setup.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/sidecar-configure.js ...

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/sidecar-status.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/sidecar-rollback.js --reenable-original

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/run-sidecar.js --skip-delivery

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
1. Before changing sidecar compatibility logic, inspect the upstream `SKILL.md`.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
1. Before changing sidecar compatibility logic, inspect the upstream `SKILL.md`.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
1. Before changing sidecar compatibility logic, inspect the upstream `SKILL.md`.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The documentation confirms that direct Feishu credentials remain in ~/.follow-builders-sidecar/credentials.json, which implies persistent local secret storage. Even if intended to stay local, plaintext or weakly protected credential files are attractive targets for other local processes, backups, or accidental disclosure.

Content

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

md
- The sidecar does not modify the upstream `follow-builders` repo.
- The sidecar does not send local files to arbitrary third-party endpoints.
- OpenClaw and Feishu routing are used only to deliver the digest the user asked for.
- Direct Feishu app credentials, when configured, stay in `~/.follow-builders-sidecar/credentials.json` and are not intended for repository storage.
- The sidecar's own local state lives under `~/.follow-builders-sidecar/`.

## Trust statement

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/prepare-digest-local.js (reported line 71)May include surrounding context.

js
}
  }

  return prompts;
}

export {

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/sidecar-common.js (reported line 710)May include surrounding context.

js
}
  }

  return prompts;
}

export {

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
const REPO_DIR = join(SCRIPT_DIR, '..');
const SIDECAR_HOME = join(homedir(), '.follow-builders-sidecar');
const SIDECAR_CONFIG_PATH = join(SIDECAR_HOME, 'config.json');
const SIDECAR_CREDENTIALS_PATH = join(SIDECAR_HOME, 'credentials.json');
const SIDECAR_STATE_PATH = join(SIDECAR_HOME, 'state.json');
const ORIGINAL_CONFIG_PATH = join(homedir(), '.follow-builders', 'config.json');

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · README.zh-CN.md (reported line 53)May include surrounding context.

md
const REPO_DIR = join(SCRIPT_DIR, '..');
const SIDECAR_HOME = join(homedir(), '.follow-builders-sidecar');
const SIDECAR_CONFIG_PATH = join(SIDECAR_HOME, 'config.json');
const SIDECAR_CREDENTIALS_PATH = join(SIDECAR_HOME, 'credentials.json');
const SIDECAR_STATE_PATH = join(SIDECAR_HOME, 'state.json');
const ORIGINAL_CONFIG_PATH = join(homedir(), '.follow-builders', 'config.json');

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · README.zh-CN.md (reported line 98)May include surrounding context.

md
const REPO_DIR = join(SCRIPT_DIR, '..');
const SIDECAR_HOME = join(homedir(), '.follow-builders-sidecar');
const SIDECAR_CONFIG_PATH = join(SIDECAR_HOME, 'config.json');
const SIDECAR_CREDENTIALS_PATH = join(SIDECAR_HOME, 'credentials.json');
const SIDECAR_STATE_PATH = join(SIDECAR_HOME, 'state.json');
const ORIGINAL_CONFIG_PATH = join(homedir(), '.follow-builders', 'config.json');

Static analysis

No suspicious patterns detected.