Back to skill

Security audit

Feishu Common

Security checks for vulnerabilities and agentic risk

Overview

This Feishu helper has a coherent purpose, but it handles tenant credentials in ways that can leak or overexpose them.

Install only if you trust the publisher and dependent Feishu skills, and configure a dedicated low-scope Feishu app credential. Review or patch the helper so authenticated requests are restricted to Feishu API hosts, secrets come from a scoped secret mechanism, and the token cache uses private permissions or a proper secret store.

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

T09 · Insecure Skill Coding Practices

Error
Location
index.js:106
Finding

Unrestricted authenticated requests can disclose the Feishu tenant token to arbitrary hosts

Content
View full analysis

Vulnerability Details

File Location: index.js:106-136
Vulnerability Type: Unrestricted credential forwarding
Risk Level: High

Vulnerable Code

javascript
async function fetchWithAuth(url, options = {}) {
    let token = await getToken();
    let headers = { ...options.headers, 'Authorization': `Bearer ${token}` };
    
    try {
        let res = await fetchWithRetry(url, { ...options, headers });
        
        // Handle JSON Logic Errors (200 OK but code != 0)
        const clone = res.clone();
        try {
            const data = await clone.json();
            // Codes for invalid token: 99991663, 99991664, 99991661, 99991668
            if ([99991663, 99991664, 99991661, 99991668].includes(data.code)) {
                throw new Error('TokenExpired');
            }
        } catch (jsonErr) {
            // If response isn't JSON or TokenExpired, ignore here
            if (jsonErr.message === 'TokenExpired') throw jsonErr;
        }
        
        return res;

    } catch (e) {
        if (e.message.includes('HTTP 401') || e.message === 'TokenExpired') {
            console.warn(`[FeishuClient] Token expired. Refreshing...`);
            token = await getToken(true);
            headers = { ...options.headers, 'Authorization': `Bearer ${token}` };
            return await fetchWithRetry(url, { ...options, headers });
        }
        throw e;
    }
}

Technical Analysis

fetchWithAuth accepts an unrestricted URL and unconditionally attaches the Feishu tenant bearer token to the request. It does not validate the URL scheme, hostname, port, or origin before transmitting the credential.

The declared purpose of this helper is to make authenticated Feishu API requests. Therefore, attaching a Feishu token to non-Feishu destinations exceeds the minimum network privileges required by the Skill. The automatic token-refresh branch can also send ...[truncated 1560 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse requests with the standard URL class and reject malformed URLs.
  2. Require the https: scheme.
  3. Enforce an explicit allowlist of approved Feishu API hosts, such as the exact hostname required by the deployment.
  4. Prefer accepting relative Feishu API paths and joining them to a hardcoded trusted base URL rather than accepting arbitrary absolute URLs.
  5. Reject URLs containing unexpected ports, embedded credentials, or hostnames that merely end with a trusted-looking string.
  6. Ensure authorization headers are never forwarded across origins during redirects. Prefer disabling automatic redirects or manually validating every redirect destination.
  7. Separate generic unauthenticated fetching from authenticated Feishu requests so the credential-bearing function cannot be reused as a general-purpose network helper.
  8. Add tests confirming that HTTP URLs, external hosts, deceptive subdomains, and cross-origin redirects are rejected before token acquisition or transmission.

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:91
Finding

Feishu tenant access token is cached in plaintext without explicit restrictive permissions

Content
View full analysis

Vulnerability Details

File Location: index.js:7, 91-96
Vulnerability Type: Insecure local storage of authentication credentials
Risk Level: Medium

Vulnerable Code

javascript
const TOKEN_CACHE_FILE = path.resolve(__dirname, '../../memory/feishu_token.json');
javascript
try {
    const cacheData = { token: data.tenant_access_token, expire: now + data.expire };
    const cacheDir = path.dirname(TOKEN_CACHE_FILE);
    if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true });
    fs.writeFileSync(TOKEN_CACHE_FILE, JSON.stringify(cacheData, null, 2));
} catch (e) {}

Technical Analysis

The tenant access token is stored as plaintext JSON in a shared parent-relative memory directory. Neither the directory nor the token file is created with explicit owner-only permissions.

Node.js file creation permissions consequently depend on platform defaults and the process umask. A permissive runtime configuration can make the cache readable by other local users, services, or components. Existing files are also overwritten without verifying their ownership, type, or permissions.

The empty catch block suppresses cache-write errors, including security-relevant permission and filesystem failures. This makes insecure or unexpected cache behavior difficult to detect.

Attack Path

  1. The Skill authenticates to Feishu and receives a tenant access token.
  2. It creates ../../memory/feishu_token.json using default filesystem permissions.
  3. A local user or process with access to the parent memory directory locates and reads the JSON file.
  4. The reader extracts the plaintext token value.
  5. The token is used to call Feishu APIs until expiration or revocation.

Exploitation depends on local filesystem access and the effective permissions produced by the runtime environment. Multi-user systems, shared application directories, containers with shared volumes, and environ ...[truncated 593 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create the cache directory with owner-only permissions such as 0700.
  2. Create the token file with an explicit mode of 0600.
  3. Verify the ownership, type, and permissions of an existing cache file before reading from or writing to it.
  4. Use atomic file creation and replacement to reduce race conditions and avoid following attacker-controlled symbolic links.
  5. Store credentials in an operating-system credential manager or dedicated secret store where available.
  6. Avoid a shared parent-relative cache location; use a private application-specific state directory.
  7. Delete expired cache entries and provide a secure token-cache cleanup mechanism.
  8. Replace the empty catch blocks with sanitized error reporting that does not expose token values but makes permission and integrity failures observable.
  9. Apply least-privilege Feishu application scopes so disclosure of a tenant token has the smallest possible impact.
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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (11)

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The dotenv load from ../../.env is direct credential access to a shared secret store outside the skill directory. In an agent environment, this pattern is high risk because a skill with broad filesystem access can appropriate credentials not intended for it and then use them to authenticate to external services.

Content

Scanner excerpt · index.js (reported line 4)May include surrounding context.

js
const fs = require('fs');
const path = require('path');
// const https = require('https'); // Unused
require('dotenv').config({ path: path.resolve(__dirname, '../../.env'), quiet: true });

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

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

js
}

/**
 * Get Tenant Access Token (Cached)
 */
async function getToken(forceRefresh = false) {
    const now = Math.floor(Date.now() / 1000);

Known Vulnerable Dependency: axios==1.13.5 — 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
97% confidence
Finding

The lockfile pins axios 1.13.5, and the supplied advisories include high-severity issues such as SSRF-related NO_PROXY bypass and prototype-pollution-assisted MITM/credential theft scenarios. Because this is a dependency manifest, the vulnerable package is genuinely present in the build and could be exercised anywhere the skill makes outbound HTTP requests, especially if proxy settings, redirects, or attacker-influenced destinations are involved.

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
92% confidence
Finding

form-data 4.0.5 is included transitively and the referenced CRLF injection advisory can enable multipart header manipulation if attacker-controlled field names or filenames are passed into form construction. In a skill context that may upload files or proxy user-provided content to external APIs, this can lead to request smuggling-like effects, malformed requests, or injection into downstream services.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: axios==1.13.5 — 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
86% confidence
Finding

The dependency specification ^1.6.0 can resolve to later 1.x axios releases, and the supplied analysis indicates resolution to axios 1.13.5 with multiple known advisories, including SSRF and man-in-the-middle related issues. In a shared API/authentication utility for Feishu integrations, a vulnerable HTTP client is more dangerous because it likely handles tokens, outbound requests, and proxy behavior across multiple skills.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill explicitly loads secrets from a shared ../../.env file and binds FEISHU_APP_ID and FEISHU_APP_SECRET into runtime state without any visible authorization boundary or stated business need in this file. In an agent-skill environment, reaching outside the skill directory for shared credentials increases the blast radius and can enable unauthorized use of tenant-level API access if the skill is invoked by untrusted workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file loads application credentials and sends them to Feishu to obtain a tenant token, but there is no disclosure, consent, or visible control in this file indicating when or why those credentials will be used. That secrecy/opacity is dangerous in an agent context because users or operators may unknowingly grant the skill the ability to act against an external tenant API.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code mints Feishu tenant access tokens and performs authenticated outbound requests, but the file provides no guardrails such as allowlisted endpoints per action, authorization checks, or a declared user-facing purpose for remote access. In a skill ecosystem, unexplained token minting plus outbound network capability can be abused to access tenant resources beyond the user's expectations.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: follow-redirects==1.15.11 — 1 advisory(ies): CVE-2026-40895 (follow-redirects leaks Custom Authentication Headers to Cross-Domain Redirect Ta)

Low
Category
Supply Chain
Confidence
91% confidence
Finding

follow-redirects 1.15.11 is present as a transitive dependency of axios, and the cited issue indicates authentication headers may leak across cross-domain redirects. This is a real supply-chain risk in applications performing authenticated HTTP requests, though practical impact depends on whether the skill follows redirects while sending sensitive headers.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

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

json
"test": "echo \"No tests specified\" && exit 0"
  },
  "dependencies": {
    "axios": "^1.6.0",
    "dotenv": "^16.3.1"
  },
  "author": "OpenClaw Evolution",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

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

json
},
  "dependencies": {
    "axios": "^1.6.0",
    "dotenv": "^16.3.1"
  },
  "author": "OpenClaw Evolution",
  "license": "MIT"