Back to skill

Security audit

feishu-calendar

Security checks for vulnerabilities and agentic risk

Overview

This Feishu calendar skill matches its general purpose, but it has unsafe calendar write/delete behavior, silent fallbacks to primary calendars, and persistent syncing of untrusted calendar text into agent state.

Review this skill carefully before installing. Use only narrowly scoped Feishu credentials, avoid running cleanup/setup/sync routine scripts until calendar targets and side effects are fixed, remove primary-calendar fallbacks, add confirmations or dry-run modes for writes and deletes, escape imported event text before writing agent state, and update vulnerable dependencies.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T02 · Agent Memory Poisoning

Error
Location
sync.js:35
Finding

Unsanitized Remote Calendar Content Is Persisted in Agent State

Content
View full analysis
{ const t = parseInt(e.start_time.timestamp); return t < (Date.now()/1000 + 86400); }); if (next24h.length === 0) { calendarSection = "## 📅 Calendar (Next 24h)\n\n- No upcoming events in the next 24 hours.\n"; } else { next24h.forEach(e => { const start = getTimestampCST( parseInt(e.start_time.timestamp) * 1000 ).split(' ')[1]; calendarSection += `- [ ] ${start} - ${e.summary}\n`; }); } const calendarRegex = /## (?:📅 )?Calendar.*?(?=\n## |$)/s; if (calendarRegex.test(heartbeatContent)) { heartbeatContent = heartbeatContent.replace( calendarRegex, calendarSection.trim() ); } else { const insertPos = heartbeatContent.indexOf('## Morning'); if (insertPos !== -1) { heartbeatContent = heartbeatContent.slice(0, insertPos) + calendarSection + "\n" + heartbeatContent.slice(insertPos); } else { heartbeatContent += "\n" + calendarSection; } } fs.writeFileSync(heartbeatPath, heartbeatContent, 'utf8'); console.log("✅ Synced to HEARTBEAT.md"); } ``` ### Technic ...[truncated 2249 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
lib/CalendarManager.js:12
Finding

Silent Calendar Fallback Can Read or Modify an Unintended Primary Calendar

Content
View full analysis
c.summary.includes(searchKeyword) || c.summary.includes("OpenClaw") ); if (!target && calendars.length > 0) target = calendars[0]; // Fallback return target; } catch (e) { console.error(`[CalendarManager] Error getting calendar: ${e.message}`); return null; } } ``` Read operations silently fall back to the primary calendar after an access failure: ```js let res = await this.client.calendar.calendarEvent.list({ path: { calendar_id: calendarId }, params: params }); if (res.code !== 0) { if (calendarId !== 'primary') { console.log( `[CalendarManager] Access failed for ID ${calendarId}, ` + `falling back to 'primary'...` ); res = await this.client.calendar.calendarEvent.list({ path: { calendar_id: 'primary' }, params: params }); } } ``` Write operations use the same fail-open behavior: ```js const res = await this.client.calendar.calendarEvent.create({ path: { calendar_id: calendarId }, data: eventData }); if (res.code !== 0) { if (calendarId !== 'primary') { console.log( `[CalendarManager] Create f ...[truncated 3070 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
setup_routine.js:18
Finding

Setup and Synchronization Commands Perform Broad Destructive and Undocumented Recurring Operations

Content
View full analysis
Remediation
View remediation
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (41)

Known Vulnerable Dependency: protobufjs==7.5.4 — 12 advisory(ies): CVE-2026-44294 (protobuf.js: Denial of service from crafted field names in generated code); CVE-2026-44293 (protobuf.js: Code injection through bytes field defaults in generated toObject c); CVE-2026-44289 (protobuf.js: Denial of service through unbounded protobuf recursion) +9 more

Critical
Category
Supply Chain
Confidence
97% confidence
Finding

protobufjs 7.5.4 is reported with numerous severe advisories including denial of service and possible code-generation/injection issues. Even though this lockfile alone does not prove the dangerous code paths are used, the presence of a package with install-script support and protobuf parsing/generation functionality creates meaningful risk if the skill processes untrusted protobuf schemas or messages, making this the most serious dependency issue in the file.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
2. **Execute**: Run `create.js` with `--attendees` set to the requester's ID.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

When event creation fails for a specified calendar, the code silently retries the write on the 'primary' calendar. This can result in events being created in the wrong calendar, causing unauthorized or unintended data modification and possible leakage of sensitive event content to another calendar context.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: axios==1.13.4 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
98% confidence
Finding

axios 1.13.4 is flagged with multiple advisories, including SSRF-related proxy bypass and prototype-pollution-assisted request/credential issues. Because this skill integrates with external Feishu/Lark APIs, an HTTP client vulnerability is materially relevant: if attacker-controlled URLs, headers, proxy settings, or redirect flows are ever introduced elsewhere in the skill, these flaws could enable request redirection, credential leakage, or response hijacking.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
90% confidence
Finding

form-data 4.0.5 is flagged for CRLF injection via unescaped multipart field names/filenames. If any part of the skill later constructs multipart requests from attacker-controlled input, this can lead to header injection or malformed requests to upstream services.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
92% confidence
Finding

ws 8.19.0 is flagged for memory disclosure and memory-exhaustion DoS issues. If the Feishu/Lark SDK uses WebSocket functionality for event streams or messaging, a reachable websocket path could expose the process to denial of service or unintended data exposure from malicious peers.

Content

No source excerpt is available for this finding.

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

js
const Lark = require('@larksuiteoapi/node-sdk');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env') });

const APP_ID = process.env.FEISHU_APP_ID;
const APP_SECRET = process.env.FEISHU_APP_SECRET;

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

js
const Lark = require('@larksuiteoapi/node-sdk');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env') });

const APP_ID = process.env.FEISHU_APP_ID;
const APP_SECRET = process.env.FEISHU_APP_SECRET;

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

js
const Lark = require('@larksuiteoapi/node-sdk');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env') });

const APP_ID = process.env.FEISHU_APP_ID;
const APP_SECRET = process.env.FEISHU_APP_SECRET;

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

js
const Lark = require('@larksuiteoapi/node-sdk');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env') });

const APP_ID = process.env.FEISHU_APP_ID;
const APP_SECRET = process.env.FEISHU_APP_SECRET;

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 · lib/CalendarManager.js (reported line 2)May include surrounding context.

js
const Lark = require('@larksuiteoapi/node-sdk');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env') });

const APP_ID = process.env.FEISHU_APP_ID;
const APP_SECRET = process.env.FEISHU_APP_SECRET;

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

js
const Lark = require('@larksuiteoapi/node-sdk');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env') });

const APP_ID = process.env.FEISHU_APP_ID;
const APP_SECRET = process.env.FEISHU_APP_SECRET;

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

js
const Lark = require('@larksuiteoapi/node-sdk');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env') });

const APP_ID = process.env.FEISHU_APP_ID;
const APP_SECRET = process.env.FEISHU_APP_SECRET;

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

js
const Lark = require('@larksuiteoapi/node-sdk');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env') });

const APP_ID = process.env.FEISHU_APP_ID;
const APP_SECRET = process.env.FEISHU_APP_SECRET;

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Loading a shared .env file is a credential-access pattern because it retrieves sensitive application secrets into this script's runtime. If this skill is invoked in an untrusted or loosely governed environment, those credentials can be leveraged to perform authenticated Feishu operations beyond the minimum necessary task.

Content

Scanner excerpt · setup_shared.js (reported line 3)May include surrounding context.

js
const { program } = require('commander');
const Lark = require('@larksuiteoapi/node-sdk');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env') });

const APP_ID = process.env.FEISHU_APP_ID;
const APP_SECRET = process.env.FEISHU_APP_SECRET;

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script creates calendars remotely and assigns ACL roles to arbitrary user-supplied OpenIDs, including the owner role, with no authorization checks, allowlist, or validation of intended recipients. In a skill context without a clearly stated administrative purpose, this capability can be abused to provision resources and grant access to sensitive scheduling data or transfer control of calendars.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases 'Mark this task' and especially 'Remind me to...' are broad natural-language cues that can match ordinary conversation and cause the skill to create calendar events without sufficiently explicit user intent. In a calendar-management skill that performs write actions, ambiguous activation increases the risk of unintended event creation, attendee exposure, or workflow execution from casual phrasing.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The script loads Feishu application credentials from a local .env file and immediately uses them to access a remote calendar API. Even if the stated function is to check a calendar, directly consuming locally stored secrets in a skill increases the risk of unintended secret exposure or unauthorized API use, especially when no access controls, scoping validation, or user consent mechanisms are present.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill fetches calendar events, which may contain sensitive scheduling and meeting-title information, from a remote API with only generic console logging and no explicit consent or warning to the user. In an agent/skill context, silent retrieval of personal or organizational calendar data is risky because users may not realize sensitive data is being accessed and displayed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This script performs irreversible deletion of calendar events through the API with no confirmation prompt, dry-run mode, or secondary validation beyond checking for empty summaries. In an agent or automation context, that makes accidental or overbroad data destruction more likely, especially if the wrong calendar is selected via fallback to the primary calendar.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

With no manifest or declared purpose available, accessing FEISHU_APP_ID and FEISHU_APP_SECRET introduces a credential-handling capability that is not justified by any stated intent. This goes beyond a simple local data transformation and enables authenticated access to an external calendar service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script performs a state-changing action against a calendar API and explicitly enables attendee notifications without any confirmation step, dry-run mode, or clear warning before sending. In an agent or automation context, this increases the risk of unintended meeting creation, spam invitations, and accidental actions on the wrong calendar, especially because the script can auto-select a calendar and retry on 'primary'.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The event timestamps are always sent with the timezone set to 'Asia/Shanghai', which forces a specific locale behavior regardless of the user's environment or intent. This is a natural-language policy issue because it imposes a locale-specific setting without opt-in or explanation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

If listing events for the requested calendar fails, the code silently retries against the 'primary' calendar instead of surfacing the error. This can cause the caller to read events from a different calendar than intended, breaking authorization expectations and potentially exposing unrelated calendar data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code performs a network call that transmits calendar event contents, including summary, description, and timing data, to the Lark/Feishu API. Although there is error logging, there is no confirmation prompt, user-facing disclosure, or explanatory comment warning that user data will be sent to an external service.

Content

No source excerpt is available for this finding.