Back to skill

Security audit

feishu-memory-recall

Security checks for vulnerabilities and agentic risk

Overview

The skill's Feishu search purpose is mostly clear, but it handles broad private chat data and stores a Feishu access token on disk without clear disclosure or restrictive permissions.

Install only if you are comfortable letting the skill read Feishu credentials, discover tracked Feishu group IDs from the local OpenClaw session store, fetch message content from tracked chats, and persist event logs locally. Treat the plaintext token cache as the main issue: restrict local file access, keep the memory directory out of backups/indexers, and prefer a version that stores tokens with 0600 permissions or only in process memory.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:54
Finding

Feishu Tenant Access Token Stored in Plaintext Without Restrictive Permissions

Content
View full analysis

Vulnerability Details

File Location: index.js, lines 54–56
Vulnerability Type: Plaintext storage of sensitive authentication data
Risk Level: Medium

js
const tokenData = { token: data.tenant_access_token, expire: Math.floor(Date.now() / 1000) + data.expire - 60 };
fs.writeFileSync(TOKEN_PATH, JSON.stringify(tokenData));
return tokenData.token;

Technical Analysis

The Skill stores the Feishu tenant access token in memory/feishu_token.json as plaintext. The fs.writeFileSync call does not specify a restrictive file mode, so the resulting permissions depend on the process umask or the permissions of an existing file.

The token is also placed in the agent's memory directory. This increases its potential exposure to local users, other processes running under accessible accounts, backup or synchronization systems, and tooling that indexes or processes agent memory.

Caching the token is not strictly required for the declared search and digest functionality; it is a performance optimization. Although the token expires, anyone who obtains it before expiration may replay it against Feishu APIs. The token's effective privileges are those granted to the Feishu application.

The related network behavior is otherwise consistent with the declared functionality: the application credentials are sent only to the official Feishu authentication endpoint, and the bearer token is sent only to official Feishu API endpoints. No transmission of credentials or message data to an unrelated destination was identified.

Attack Path

  1. A user invokes recall, search, or digest.
  2. The Skill sends the configured application ID and secret to Feishu's official authentication endpoint and receives a tenant access token.
  3. The Skill writes that token in plaintext to memory/feishu_token.json.
  4. A local user, process, backup system, synchronization service, or memory-indexing component with acces ...[truncated 852 chars]
Remediation
View remediation

Remediation Suggestions

  • Prefer keeping tenant access tokens in memory and requesting a new token after process restart rather than persisting them.
  • If persistent caching is necessary, store the cache outside the agent memory directory in a dedicated credential or runtime-state directory.
  • Create the containing directory with mode 0700 and write the token file with mode 0600.
  • Use an atomic write procedure: create a new file with exclusive and restrictive permissions, write the data, flush it, and rename it into place.
  • Before reading an existing cache, verify that it is a regular file, is owned by the expected user, and is not accessible by group or other users.
  • Delete expired token files rather than leaving stale credentials on disk.
  • Avoid including the credential cache in backups, synchronization, source control, logs, or memory-indexing pipelines.
  • Run the Skill under a dedicated least-privileged operating-system account.
  • Restrict the Feishu application to only the API scopes and chat access required for message retrieval.
  • Consider using an operating-system credential store or managed secret-storage service if durable token storage is unavoidable.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (11)

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

js
const path = require('path');

try {
    require('dotenv').config({ path: path.resolve(__dirname, '../../.env') });
} catch (e) {}

const MEMORY_DIR = path.resolve(__dirname, '../../memory');

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises capabilities that require environment-variable access and network access, but it does not declare any explicit tool scope or permissions boundary. In a skill that searches across all Feishu groups and DMs and reads local session state, this omission can lead to over-broad execution in hosts that rely on manifest metadata for least-privilege enforcement or user review.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly enables cross-group message search, digests, and event sharing across all Feishu groups and DMs, but the description does not warn users that data from separate conversations will be aggregated and exposed across contexts. This creates a significant privacy and confidentiality risk because users or operators may invoke the skill without understanding that sensitive information from one group can be surfaced in another workflow or summary.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill reads the local OpenClaw sessions store to infer active Feishu groups, which exposes metadata from outside the skill's declared inputs. Even though it only reads IDs/session keys rather than message bodies, this is privacy-sensitive local data access and can reveal cross-group membership or activity without explicit user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The recall and search commands aggregate messages across multiple groups and output message content without any warning, consent gate, or narrowing of scope. In an agent skill context, cross-group retrieval materially increases privacy risk because a caller can enumerate a user's messages or search sensitive terms across conversations that participants may expect to remain context-separated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The digest command summarizes recent activity across all tracked groups and includes message previews, effectively aggregating private discussion content into a single report. This increases the blast radius of otherwise compartmentalized conversations and can expose sensitive content to users who would not normally review every group.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill documents a log-event command that writes event content into RECENT_EVENTS.md and dated memory logs, but it does not warn that supplied data will be stored persistently on disk. Persistent markdown logging can retain sensitive operational details, personal data, or secrets far beyond the original context, increasing exposure through later reads, backups, or accidental sharing.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The top-of-file command documentation says recall, search, and digest work "across all groups," which implies all accessible Feishu groups. In code, search and digest iterate only over loadGroups(), and recall checks only tracked groups plus a single P2P chat, so the documented scope overstates actual behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Reading local session metadata without disclosure is a privacy-sensitive behavior because it inspects files outside the skill's immediate inputs to discover group identifiers. While the data accessed appears limited to session keys rather than credentials or message content, it still reveals local application state and cross-group relationships.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency uses a caret range (^14.0.3), which allows automatic installation of newer compatible releases rather than a single fixed version. This can introduce supply-chain risk if a future upstream release is compromised or behaves unexpectedly, though the package.json alone does not indicate active exploitation.

Content

Scanner excerpt · package.json (reported line 7)May include surrounding context.

json
"description": "Cross-group memory, search, and event sharing for OpenClaw Feishu agents",
  "main": "index.js",
  "dependencies": {
    "commander": "^14.0.3",
    "dotenv": "^17.2.3"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency uses a caret range (^17.2.3), permitting resolution to later releases within the major version. That increases supply-chain exposure because builds may pull in unreviewed code over time, even if the current declared version appears safe.

Content

Scanner excerpt · package.json (reported line 8)May include surrounding context.

json
"main": "index.js",
  "dependencies": {
    "commander": "^14.0.3",
    "dotenv": "^17.2.3"
  }
}