Back to skill

Security audit

Elastolink Meeting Skills

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real Elastolink meeting helper, but it handles bearer tokens and meeting exports in ways that could expose sensitive data or overwrite local configuration.

Review this before installing if your meetings contain confidential or personal information. Use only a minimally scoped Elastolink token, avoid production or long-lived credentials, assume the token may appear in command logs or stdout, and do not run export tools unless you are authorized to retrieve and store that meeting content.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/set-token.cjs:9
Finding
Bearer Token Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/set-token.cjs:9-16`; invoked as documented in `SKILL.md:21-24` **Vulnerability Type**: Secret exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```javascript const token = process.argv[2]; if (!token) { console.error('Usage: node set-token.js <token>'); process.exit(1); } const envPath = path.join(__dirname, '..', '.env'); fs.writeFileSync(envPath, `ELASTOLINK_TOKEN=${token}\n`); ``` The documented workflow explicitly places the token in the command: ```markdown 1. Run `node D:\workspace\demo\elastolink\scripts\get-token.cjs` 2. If the output is `NO_TOKEN`, ask the user to enter a token and save it: - User enters a token in the format `sk-xxx` - Run `node D:\workspace\demo\elastolink\scripts\set-token.cjs <token>` ``` ### Technical Analysis The script receives the bearer token through `process.argv`. Command-line arguments may be exposed through operating-system process inspection, shell history, terminal telemetry, agent execution traces, audit systems, and command logging. This is especially relevant in an AI-agent workflow because the agent must interpolate the user-provided secret into a command string. That command may consequently be retained independently of the destination `.env` file. ### Attack Path 1. A user provides an Elastolink bearer token to the agent. 2. The agent invokes `set-token.cjs` with the token embedded in the command line. 3. The command or process arguments are captured by shell history, process-monitoring tools, agent logs, or execution telemetry. 4. A local user or log reader obtains the exposed token. 5. The attacker submits the token as an `Authorization: Bearer` credential to the configured MCP endpoint. 6. Subject to the token's server-side privileges, the attacker can access meeting-service operations available to that credential. ### Impact Assessment Successful exploitation discloses the Elastolink bearer token. An ...[truncated 330 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not accept secrets through command-line arguments. - Read the token from masked interactive input or standard input without echoing it. - Prefer an operating-system credential manager or secret-management service over a plaintext project file. - Ensure agent execution logs and telemetry redact authentication credentials. - Update `SKILL.md` so the documented workflow never interpolates a token into a command. - If standard input is used, pass it directly to the process rather than constructing a shell command containing the secret. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get-token.cjs:9
Finding
Token Presence Check Prints the Complete Credential<![CDATA[ ## Vulnerability Details **File Location**: `scripts/get-token.cjs:9-19` **Vulnerability Type**: Plaintext secret disclosure through standard output **Risk Level**: Medium ### Vulnerable Code ```javascript const envPath = path.join(__dirname, '..', '.env'); if (!fs.existsSync(envPath)) { console.log('NO_TOKEN'); process.exit(1); } const content = fs.readFileSync(envPath, 'utf-8'); const match = content.match(/ELASTOLINK_TOKEN=(.+)/); if (match) { console.log(match[1].trim()); } else { console.log('NO_TOKEN'); process.exit(1); } ``` ### Technical Analysis Although the workflow only needs to determine whether a token exists, the script prints the entire credential to standard output. Standard output is commonly captured by agent transcripts, terminal logs, continuous-integration systems, monitoring tools, and wrapper processes. This behavior also contradicts the documented design statement that the AI does not need to handle the token string. Printing the token causes the credential to cross an unnecessary trust boundary from local secret storage into the agent's output channel. ### Attack Path 1. A valid token is stored in the project-level `.env` file. 2. The agent runs `get-token.cjs` as part of the documented token check. 3. The script reads and prints the complete bearer token. 4. The output is retained in an agent transcript, terminal log, execution trace, or automation log. 5. An attacker with access to that output retrieves the token. 6. The attacker authenticates to the Elastolink MCP service and invokes operations permitted to the compromised credential. ### Impact Assessment The vulnerability can disclose the complete bearer token to parties able to read captured process output. The attacker obtains the same service authorization as the token holder and may access meeting metadata, content, and exports within the token's authorization scope. No additional host privileges are directly obtained. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Change the script to return only a non-sensitive status such as `TOKEN_PRESENT` or `NO_TOKEN`. - Keep token retrieval internal to `mcp-call.cjs`; do not expose the credential to stdout or the agent. - Redact bearer tokens from existing execution logs where operationally possible. - Add automated tests that fail if token values appear in stdout or error output. - Restrict diagnostic logging so authentication headers and secret-file contents are never emitted. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/set-token.cjs:15
Finding
Token File Is Written Without Explicit Access Restrictions and Existing Environment Data Is Truncated<![CDATA[ ## Vulnerability Details **File Location**: `scripts/set-token.cjs:15-16` **Vulnerability Type**: Insecure secret storage and destructive configuration overwrite **Risk Level**: Medium ### Vulnerable Code ```javascript const envPath = path.join(__dirname, '..', '.env'); fs.writeFileSync(envPath, `ELASTOLINK_TOKEN=${token}\n`); ``` ### Technical Analysis The token is persisted as plaintext in a project-level `.env` file without requesting owner-only permissions or verifying the ownership and permissions of an existing file. On systems where the effective creation mask or existing file mode is permissive, another local account may be able to read the bearer token. In addition, `writeFileSync` replaces the complete contents of the existing `.env` file. Any unrelated configuration or secrets already stored in that file are destroyed. If the file already exists, writing it does not necessarily correct insecure pre-existing permissions. ### Attack Path Credential-disclosure path: 1. The user invokes the token-storage workflow. 2. The script writes the bearer token to `.env` without enforcing restrictive access permissions. 3. The resulting file is readable by an unintended local account because of platform configuration or pre-existing permissions. 4. That account reads the token and uses it against the configured MCP endpoint. Configuration-loss path: 1. The project already has an `.env` file containing unrelated configuration. 2. The user saves an Elastolink token. 3. `writeFileSync` truncates the file and replaces it with one `ELASTOLINK_TOKEN` entry. 4. The application loses existing configuration, potentially causing service disruption or loss of other environment settings stored only in that file. ### Impact Assessment Credential disclosure gives a local attacker the service privileges assigned to the bearer token, potentially exposing meeting lists, details, and document exports. The destructive overwrite can cause loss of application conf ...[truncated 208 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Prefer an operating-system credential store or dedicated secret-management service. - If file storage is unavoidable, use a dedicated token file rather than a shared `.env` file. - On platforms supporting POSIX permissions, create the credential file with mode `0600` and verify that it is owned by the expected user. - Reject symlinks and unexpected file types before writing sensitive data. - Use an atomic write strategy with a securely permissioned temporary file followed by a rename. - If `.env` must be retained, parse and update only `ELASTOLINK_TOKEN` while preserving all unrelated entries. - Avoid storing the credential under a source-controlled project directory, and ensure the secret file is excluded from version control and backups that lack equivalent access controls. ]]>
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (17)

Missing User Warnings

High
Confidence
97% confidence
Finding
The skill instructs the agent to ask for a token and save it to a local .env file without an explicit warning that the credential will be persisted on disk. This can lead users to disclose secrets without informed consent, and local persistence increases the risk of later theft, accidental exposure, or reuse by other processes.

Credential Access

High
Category
Privilege Escalation
Content
```
D:\workspace\demo\elastolink\
├── .env                    # Token 存储(自动管理)
├── .session                # Session ID(自动管理)
├── scripts\
│   ├── mcp-call.cjs       # MCP 调用主脚本
Confidence
95% confidence
Finding
The skill explicitly documents storing an access token in a project-local .env file, which is a credential storage pattern with material security risk. Even though the file reference is descriptive, normalizing plaintext secret storage in a known workspace path makes token discovery, accidental check-in, or local exfiltration more likely.

Credential Access

High
Category
Privilege Escalation
Content
const fs = require('fs');
const path = require('path');

const envPath = path.join(__dirname, '..', '.env');

if (!fs.existsSync(envPath)) {
  console.log('NO_TOKEN');
Confidence
88% confidence
Finding
Accessing a .env file to extract ELASTOLINK_TOKEN is direct credential access, and in this file it is immediately paired with disclosure of the secret. In the context of an MCP/meeting assistant skill, this is more dangerous because such tooling may be invoked by other automation layers, increasing the chance that credentials are exposed beyond the local developer session.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env node
/**
 * set-token.js - 保存 token 到 .env
 * 用法: node set-token.js <token>
 */
const fs = require('fs');
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
process.exit(1);
}

const envPath = path.join(__dirname, '..', '.env');
fs.writeFileSync(envPath, `ELASTOLINK_TOKEN=${token}\n`);
console.log('Token saved to .env');
Confidence
95% confidence
Finding
Building a path to a repository-local .env file is part of a workflow that stores a secret in plaintext on disk. In this skill context, the danger is elevated because MCP/server tooling often runs in developer environments where project files may be synced, shared, or committed, increasing exposure of the token.

Credential Access

High
Category
Privilege Escalation
Content
const envPath = path.join(__dirname, '..', '.env');
fs.writeFileSync(envPath, `ELASTOLINK_TOKEN=${token}\n`);
console.log('Token saved to .env');
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
const envPath = path.join(__dirname, '..', '.env');
fs.writeFileSync(envPath, `ELASTOLINK_TOKEN=${token}\n`);
console.log('Token saved to .env');
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Natural-Language Policy Violations

Medium
Confidence
72% confidence
Finding
The skill metadata and user-facing documentation are written to operate in Chinese context (`魔簧会议助手`, `会议`, Chinese workflow examples) without stating that another language can be used. If organizational policy requires avoiding forced language selection without opt-in, this is a natural-language policy concern.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger description is very broad, covering generic terms like meeting, MCP tools, and project names, which can cause the skill to activate in contexts the user did not intend. Unintended invocation is risky here because the skill is designed to access local scripts, token management, and meeting data, increasing the chance of accidental credential prompts or sensitive data access.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill advertises automated export of meeting content to Markdown or Office documents but does not warn that these operations may create files containing sensitive meeting data. In a meeting assistant context, exports can include confidential business notes or personal information, so silent file creation meaningfully increases disclosure risk.

External Transmission

Medium
Category
Data Exfiltration
Content
## Initialize (Required First)

```bash
curl -X POST https://dev.ideasprite.com/mcp \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
Confidence
88% confidence
Finding
The skill documents sending authenticated requests, including session establishment and later meeting-content retrieval, to an external server at dev.ideasprite.com. In context, this means potentially sensitive meeting metadata and content are transmitted off-host to a remote environment, increasing confidentiality risk if users are unaware, the environment is non-production, or access controls are weak.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation instructs users to enumerate historical meetings and retrieve detailed meeting content from a remote service without any privacy warning, consent check, or data-sensitivity guidance. Because meeting lists, transcripts, markdown, and office exports can contain sensitive business or personal information, this omission can lead to over-collection or disclosure of confidential data during normal use.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
This script reads a token from a local .env file and prints it directly to stdout, creating a straightforward secret-disclosure path. Even if intended for developer convenience, emitting credentials to the console makes them easy to capture via terminal history, logs, parent processes, CI output, or other tooling, and the meeting-assistant/MCP context does not justify unrestricted token exfiltration.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script discloses a sensitive credential without any warning, authentication, or confirmation step before printing it. That lowers the barrier to accidental or unauthorized exposure, especially in automation contexts where stdout may be collected or forwarded without the user's awareness.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script persists a sensitive access token in plaintext to a project .env file with no permission hardening, no warning, and no validation that the file is excluded from source control. This creates a realistic risk of accidental disclosure through commits, backups, local malware, shared workspaces, or overly broad file permissions.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
Several tool names and descriptions are presented in Chinese, while the surrounding documentation is in English, and there is no indication that this language choice is optional or required for a specific region. This can violate a language/locale policy if the skill effectively forces one language without user opt-in or justification.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The script persists the MCP session identifier to ../.session using fs.writeFileSync, but there is no confirmation prompt, user-facing log, or explanatory warning that local state will be created or overwritten. Because this is a code file, silent file writes should be disclosed when they are not clearly communicated to the user.

Static analysis

No suspicious patterns detected.