Back to skill

Security audit

memos-skill

Security checks for vulnerabilities and agentic risk

Overview

This Memos skill is mostly coherent, but it asks the agent to persist and reuse a bearer token while also enabling broad note modification and deletion actions.

Install only if you trust the Memos instance and are comfortable giving the agent access to your private notes and mutation actions. Prefer using an environment variable or secret manager for the token, or at minimum protect config.json with owner-only permissions, keep it out of version control, use a limited-scope token, and require confirmation before deletes, bulk edits, uploads, or token creation.

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
SKILL.md:353
Finding

Bearer Token Stored in a Plaintext Configuration File Without Explicit Access Controls

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:353-362
Vulnerability Type: Plaintext credential storage with insufficient file-permission hardening
Risk Level: Medium

The skill instructs the agent to write the Memos instance access token directly to config.json:

js
const config = {
  instance_url: "https://memo.example.com",
  access_token: "abc123",
  default_page_size: 10,
  default_visibility: "PRIVATE",
};

const skillDir = __dirname;
const configPath = path.join(skillDir, "config.json");

fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");

Related instructions at SKILL.md:64-74 subsequently read this plaintext token and use it as a bearer credential:

js
// Read configuration
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));

const instanceUrl = config.instance_url;
const accessToken = config.access_token;
const headers = {
  Authorization: `Bearer ${accessToken}`,
  "Content-Type": "application/json",
};

Technical Analysis

fs.writeFileSync is used without an explicit restrictive mode. Consequently, the resulting permissions depend on the runtime environment and process umask rather than being guaranteed to allow access only to the owning user. The bearer token is stored unencrypted in a predictable file inside the skill directory.

Any local account, process, backup system, artifact collector, or accidental repository commit that can read this file can recover the credential. A Memos bearer token is reusable authentication material; possession may be sufficient to impersonate the user until the token expires or is revoked.

The documentation also demonstrates passing the token in a curl authorization-header argument at SKILL.md:106-110:

bash
curl -X POST \
  -H "Authorization: Bearer $MEMOS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content":"Test content","tags":["test"]}' \
  
...[truncated 1772 chars]
Remediation
View remediation

Remediation Suggestions

  1. Store the access token in an operating-system credential manager, dedicated secret manager, or protected runtime environment rather than in the skill directory.

  2. If file-based storage is unavoidable, create the file with explicit owner-only permissions:

    js
    fs.writeFileSync(
      configPath,
      `${JSON.stringify(config, null, 2)}\n`,
      { encoding: "utf8", mode: 0o600, flag: "w" },
    );
    
  3. Before reading an existing configuration file, verify that it is owned by the expected user, is not a symbolic link, and is not accessible by group or other users.

  4. Separate non-sensitive settings from credentials. Keep instance_url, page size, and visibility in config.json, while resolving the token from a secret store at runtime.

  5. Add config.json to .gitignore and provide a redacted config.example.json containing placeholders only.

  6. Avoid exposing the bearer token in command-line arguments. Use a protected temporary curl configuration, a secured header file, or another mechanism that does not make the expanded token visible in the process argument list. Ensure any temporary file is created with mode 0600 and deleted promptly.

  7. Never print the token in logs, errors, command traces, or confirmation messages. Redact authorization headers from diagnostics.

  8. Apply least privilege and limited lifetimes to access tokens. Document immediate revocation and rotation procedures for suspected disclosure.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger language is very broad and can activate on generic note-taking or memo-related phrases, causing the skill to run in situations the user may not intend. Because this skill can read, update, delete, and transmit data to an external Memos instance, over-triggering raises the risk of unintended access or modification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest description is entirely in Chinese and frames activation and behavior in that locale without stating that the skill is Chinese-only or offering an opt-in language choice. Under the policy, language constraints should either be optional for the user or clearly documented as a justified regional limitation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation tells the agent to store an access token in a local config.json file without warning about credential persistence risks. Persisting bearer tokens in plaintext increases exposure through local file disclosure, backups, logs, or accidental repository inclusion, enabling unauthorized access to the user's Memos account.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

const accessToken = config.access_token;

text

#### 2. 用 curl 调用 memos API

```bash
curl -X POST \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill documents update and delete operations without requiring explicit user confirmation or warning about destructive consequences. In an agent setting, that can lead to accidental loss or modification of notes if the skill is triggered broadly or the user's request is ambiguous.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill includes functionality to create personal access tokens, which expands beyond ordinary memo CRUD into credential lifecycle management. That increases the chance the agent could mint or handle long-lived credentials with broader privileges than necessary, creating a security-sensitive capability not clearly required for the stated purpose.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly instructs the agent to persist a user-provided access token to disk and reuse it later. Long-lived local storage of reusable bearer credentials materially increases the blast radius of file compromise and can enable silent future actions against the user's external service without renewed consent.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
SKILL.md:71