Back to skill

Security audit

Moltbot Plugin 2do

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but its very broad task triggers can email raw user messages through SMTP without a clear confirmation step.

Review before installing. Use an app-specific SMTP password and a dedicated mailbox if possible, build the package so `dist/main.js` exists, avoid the `npx` fallback, and consider narrowing activation to explicit task commands or adding a confirmation step before any email is sent.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Warning
Location
scripts/send-task.sh:8
Finding

Runtime Execution of an Undeclared Package Through npx

Content
View full analysis

Vulnerability Details

File Location: scripts/send-task.sh, lines 8-11
Vulnerability Type: Runtime dependency retrieval and execution
Risk Level: Medium

Vulnerable Code

bash
if [ -f "$PROJECT_DIR/dist/main.js" ]; then
    node "$PROJECT_DIR/dist/main.js" "$@"
else
    npx --prefix "$PROJECT_DIR" tsx "$PROJECT_DIR/src/main.ts" "$@"
fi

Technical Analysis

When dist/main.js is absent, the wrapper invokes tsx through npx. However, tsx is not declared as a direct dependency or development dependency in package.json, and it is not a direct importer dependency in pnpm-lock.yaml.

Consequently, a suitable local tsx executable is not guaranteed to exist. Depending on the installed npm version and configuration, npx may retrieve tsx from the configured package registry and execute it immediately. The effective code executed by the Skill is therefore not fully constrained by the reviewed source tree or project lockfile.

The audited artifact does not contain the dist/ directory, so this fallback is relevant to direct execution of the supplied artifact. This is a supply-chain weakness rather than evidence that the current tsx package is malicious.

Attack Path

  1. An operator invokes scripts/send-task.sh.
  2. The script checks for dist/main.js; it is absent from the audited artifact.
  3. The script executes npx --prefix "$PROJECT_DIR" tsx ....
  4. No direct, lockfile-governed tsx dependency is guaranteed to be available locally.
  5. npx resolves the executable using npm configuration and may download it from a configured registry.
  6. A compromised registry, malicious registry override, or package substitution supplies attacker-controlled package code.
  7. The downloaded package executes with the privileges and environment of the Skill process.

Impact Assessment

Successful exploitation could provide arbitrary code execution under the account running OpenClaw or the Skill. The executed package could acces ...[truncated 420 chars]

Remediation
View remediation

Remediation Suggestions

  1. Add tsx as an explicit dependency at an exact reviewed version:
json
{
  "devDependencies": {
    "tsx": "4.x.y"
  }
}
  1. Regenerate and commit the lockfile, and install dependencies using a frozen lockfile:
bash
pnpm install --frozen-lockfile
  1. Prevent npx from installing missing packages at runtime. For example:
bash
if [ -f "$PROJECT_DIR/dist/main.js" ]; then
    exec node "$PROJECT_DIR/dist/main.js" "$@"
elif [ -x "$PROJECT_DIR/node_modules/.bin/tsx" ]; then
    exec "$PROJECT_DIR/node_modules/.bin/tsx" "$PROJECT_DIR/src/main.ts" "$@"
else
    echo "Error: dist/main.js and the local tsx executable are unavailable." >&2
    exit 1
fi
  1. Prefer distributing and executing a prebuilt dist/main.js for production installations, eliminating the TypeScript runtime dependency.

  2. In CI and release workflows, verify that dist/main.js is present and built from reviewed source before publishing the Skill.

  3. Restrict npm registry configuration to trusted registries and use integrity-checked, lockfile-controlled installations.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (35)

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill is explicitly designed to trigger on very broad natural-language phrases such as reminders, statements of future intent, and ordinary conversation fragments. In an agent environment, this can cause unintended activation and silent task creation from messages the user did not mean as commands, especially across many chat channels. The context increases risk because the plugin performs an external side effect automatically by emailing extracted task content to a third-party service.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The examples encourage ambiguous trigger phrases like casual reminder language and ordinary scheduling statements without distinguishing command mode from normal conversation. This raises the likelihood of accidental invocation, which is dangerous here because the action is not local parsing only but automatic transmission of task details via SMTP to the configured 2Do inbox. In this skill context, ambiguity directly translates into unintended external actions and possible disclosure of sensitive content.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This is a clear mismatch. The declared purpose describes an end-user productivity skill for creating 2Do tasks via email from natural-language input. The supplied code chunk only configures the tsup build process for a TypeScript project. While build configuration can be a supporting file in a larger project, this chunk by itself does not exhibit any of the declared functional behavior, resource access, or integrations. Therefore the actual behavior shown is materially different from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear mismatch between the declared description and the provided code. The description claims end-user functionality for creating tasks/reminders and sending them to 2Do via email, but the actual code only configures the Vitest test runner. This code neither processes user input nor accesses email or external services. Its primary purpose is unrelated infrastructure/testing setup, so the description does not accurately represent the supplied code chunk.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Allowing no-prefix free-form input means ordinary user text can be interpreted as a task-creation request and transmitted externally via email without a clear invocation boundary. In this skill's context, that is more dangerous because the destination is an external mailbox-backed integration, creating a real risk of unintended data exfiltration, accidental task creation, and prompt-trigger ambiguity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill explicitly describes sending task details and timestamps via SMTP to a 2Do-monitored mailbox, but it does not prominently disclose to users that their content leaves the assistant context and is transmitted through an external email service/account. Users may include sensitive personal or work information in task text, so insufficient notice creates a real privacy and data-handling risk even if the transfer is part of intended functionality.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documented mail body includes the user's full original input, which may contain extra conversational context, sensitive personal data, credentials, addresses, or unrelated notes that are not necessary to create the task. Sending this verbatim to an external mailbox broadens data exposure and increases the chance of accidental leakage through mail providers, mailbox compromise, forwarding rules, or device sync.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README states that parsed task content is sent by email to 2Do, but it does not prominently warn users that message content may leave the chat platform and traverse external mail infrastructure. Users may include sensitive personal or business information in reminders, unaware that the skill forwards it via SMTP and stores it in another service. The danger is amplified because the plugin supports many messaging channels and natural-language capture, increasing the chance that sensitive conversational content is forwarded unintentionally.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill documentation encourages passing raw user messages directly to a script that sends formatted email, but it does not prominently warn that user content may leave the system and be transmitted to a third-party email destination. In this context, that omission is security-relevant because users may include sensitive personal, work, or credential-like data in free-form reminders, causing unintended external disclosure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file’s natural-language descriptions explicitly state that it extracts date/time from Chinese natural language, and the parsing logic only recognizes Chinese date/time expressions. Under the policy, language-specific behavior should either offer user choice or clearly document a justified locale constraint; this file does not show opt-in or such justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file contains natural-language comments and user-visible error/success messages in Chinese only, such as the parsing mode comments and the error output at L38. This imposes a specific language on users without opt-in or justification, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 55)May include surrounding context.

md
// === 英文前缀模式 ===

// 英文前缀(含列表):匹配 "add task to work list:" 等
const EN_PREFIX_WITH_LIST = /^(?:add\s+task|create\s+todo)\s+to\s+(.+?)\s+list\s*[::]\s*/i;

// 英文前缀:匹配 "add task:"、"remind me to" 等

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · src/task-parser.ts (reported line 14)May include surrounding context.

ts
// === 英文前缀模式 ===

// 英文前缀(含列表):匹配 "add task to work list:" 等
const EN_PREFIX_WITH_LIST = /^(?:add\s+task|create\s+todo)\s+to\s+(.+?)\s+list\s*[::]\s*/i;

// 英文前缀:匹配 "add task:"、"remind me to" 等

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · tests/task-parser.test.ts (reported line 79)May include surrounding context.

ts
// === 英文前缀模式 ===

// 英文前缀(含列表):匹配 "add task to work list:" 等
const EN_PREFIX_WITH_LIST = /^(?:add\s+task|create\s+todo)\s+to\s+(.+?)\s+list\s*[::]\s*/i;

// 英文前缀:匹配 "add task:"、"remind me to" 等

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · tests/task-parser.test.ts (reported line 80)May include surrounding context.

ts
// === 英文前缀模式 ===

// 英文前缀(含列表):匹配 "add task to work list:" 等
const EN_PREFIX_WITH_LIST = /^(?:add\s+task|create\s+todo)\s+to\s+(.+?)\s+list\s*[::]\s*/i;

// 英文前缀:匹配 "add task:"、"remind me to" 等

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file emits user-facing natural-language strings only in Chinese, including the thrown error message and generated email body labels. Under the policy, forcing a specific language without user opt-in is a locale/language policy violation unless the constraint is clearly documented and justified, which is not evident in this file.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The function copies raw user input directly into the email body, which can forward sensitive information the user may have included incidentally in their request. Because this skill sends content out via email to an external inbox, the raw text may expose private notes, credentials, personal data, or unrelated context beyond the normalized task fields.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This TypeScript test file validates date parsing exclusively with Chinese phrases such as '今天', '下周三', and '下午3点', and all descriptive strings are also in Chinese. That creates a natural-language locale constraint in the skill behavior without any visible opt-in or justification, which matches the policy-violation category for forced language/locale assumptions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

Line L33 describes the skill as supporting only Chinese/English command prefixes. This can indicate a language policy constraint in natural-language behavior without any mention of user choice, opt-in, or justification for limiting supported languages.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file's natural-language instructions, examples, and usage guidance are all presented in Chinese, which can effectively force a specific language on users. The policy allows locale constraints only when users are given a language option or when the restriction is clearly documented and justified, neither of which appears here.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The production dependency uses a caret range instead of an exact pinned version, so builds are not fully reproducible and could silently pull in a newer release with security regressions or supply-chain compromise. In this skill, nodemailer is a runtime dependency used for sending email, so unexpected dependency changes affect code that handles outbound network operations and potentially user data.

Content

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

json
"skill"
  ],
  "dependencies": {
    "nodemailer": "^7.0.13"
  },
  "devDependencies": {
    "@tsconfig/node22": "^22.0.1",

Unverifiable Dependency: nodemailer has 15 known advisory(ies) (CVE-2026-82661 (Nodemailer: CRLF injection in Nodemailer List-* header comments allows arbitrary); GHSA-2x7j-588g-ccc2 (Nodemailer: Quadratic (O(n²)) time complexity in addressparser allows remote den); CVE-2020-7769 (Command injection in nodemailer) +12 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
86% confidence
Finding

The manifest does not pin nodemailer, and the package has multiple published advisories, including historically serious issues such as command injection and parser-related denial of service. Because this skill's core function relies on nodemailer at runtime to process and send email, inability to verify the exact installed version materially increases risk compared with a non-networking helper dependency.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

This dev dependency is not pinned to an exact version, which weakens build reproducibility and allows unnoticed upstream changes during installation. Although @tsconfig/node22 is development-only and less exposed at runtime, it still participates in the build toolchain and can affect generated artifacts or CI environments.

Content

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

json
"nodemailer": "^7.0.13"
  },
  "devDependencies": {
    "@tsconfig/node22": "^22.0.1",
    "@types/node": "^22.13.1",
    "@types/nodemailer": "^7.0.4",
    "tsup": "^8.5.1",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The @types/node package is declared with a floating semver range, which permits automatic drift in the development environment. While this is primarily a typing package and not directly a runtime component, unpinned build inputs still create supply-chain and reproducibility risk.

Content

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

json
},
  "devDependencies": {
    "@tsconfig/node22": "^22.0.1",
    "@types/node": "^22.13.1",
    "@types/nodemailer": "^7.0.4",
    "tsup": "^8.5.1",
    "typescript": "^5.7.3",

Static analysis

No suspicious patterns detected.