Back to skill

Security audit

dingtalk-minutes

Security checks for vulnerabilities and agentic risk

Overview

This DingTalk minutes skill is coherent, but it needs Review because it executes an unpinned remote installer and can persist and mirror sensitive meeting content locally.

Install only if you trust the dws upstream installer, and prefer a pinned or checksum-verified install before running sh. Treat archives, mirror folders, summaries, transcripts, todos, metadata, audio URLs, and audio downloads as sensitive meeting records; keep them out of shared folders, public repos, and unmanaged cloud sync. Use --dry-run and --no-mirror when you do not want local copies propagated, and remove temporary auth logs after login.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:35
Finding

Execution of an Unpinned Remote Installation Script

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:35-39; duplicated in references/02-setup.md:7-13
Vulnerability Type: Remote payload retrieval and execution
Risk Level: Critical

Complete Code Snippet:

bash
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.sh -o /tmp/dws-install.sh
sh /tmp/dws-install.sh

Technical Analysis

The installation instructions download a shell script from the mutable main branch of an external GitHub repository and execute it without verifying a cryptographic checksum, release signature, or immutable commit identifier.

Saving the script before invoking sh avoids the literal curl | sh pattern, but it does not remove the underlying remote-code-execution trust boundary. The effective code executed by users can change after this Skill has been reviewed. Describing the upstream repository as official is not a technical integrity control and does not protect against repository compromise, maintainer account compromise, malicious branch updates, or an upstream supply-chain incident.

Remote installer execution is not the minimum privilege required for the Skill's declared read-only DingTalk functionality. A preinstalled, version-pinned dws executable would be sufficient. Although the metadata specifies a minimum CLI version, the installation command does not pin a particular release.

Attack Path

  1. An attacker compromises the upstream repository, a maintainer account, or the delivery path used for the mutable main branch.
  2. The attacker modifies scripts/install.sh to include malicious shell commands.
  3. A user follows the Skill's documented installation procedure.
  4. curl retrieves the modified script without integrity verification.
  5. sh executes the payload with all privileges available to the user running the command.
  6. The payload can access the user's files, authentication material, loca ...[truncated 883 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace the mutable main URL with an immutable, versioned release artifact or commit-specific URL.
  • Publish and verify a SHA-256 digest obtained through an independently trusted release channel.
  • Prefer a trusted package manager or signed release package over direct shell-script execution.
  • If a script remains necessary, instruct users to inspect it before execution.
  • Fail closed when checksum or signature verification fails.
  • Keep the documented version synchronized with the pinned artifact.
  • Apply the same correction to both SKILL.md and references/02-setup.md.

A hardened workflow should follow this sequence:

  1. Create a private temporary directory using mktemp -d.
  2. Download an immutable release artifact.
  3. Verify its checksum or cryptographic signature.
  4. Inspect or execute it only after successful verification.
  5. Remove the temporary directory after installation.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:38
Finding

Predictable Shared Temporary Path Used for Installer Execution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:38-39; duplicated in references/02-setup.md:12-13
Vulnerability Type: Unsafe temporary-file handling
Risk Level: Medium

Complete Code Snippet:

bash
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.sh -o /tmp/dws-install.sh
sh /tmp/dws-install.sh

Technical Analysis

The installer is written to the fixed path /tmp/dws-install.sh. Shared temporary directories are generally writable by multiple local users, and predictable filenames create opportunities for pre-creation, symbolic-link attacks, and time-of-check/time-of-use substitution.

The instructions do not securely create the file, verify its owner or type, restrict its permissions, validate its digest, or ensure that the file executed by sh is the same file produced by the download. Platform protections such as sticky-directory semantics or protected symlink settings may reduce exploitability on some systems, but the instructions should not rely on optional operating-system hardening.

Attack Path

A feasible attack depends on the target platform's temporary-directory protections:

  1. A local attacker anticipates use of the documented filename.
  2. The attacker pre-creates /tmp/dws-install.sh, creates a symbolic link at that path, or attempts to replace the file between download and execution.
  3. The victim runs the documented curl command.
  4. If local filesystem protections and permissions permit the operation, the download overwrites an unintended target or the path is substituted after download.
  5. The victim runs sh /tmp/dws-install.sh.
  6. Attacker-controlled content executes with the victim's user privileges.

Impact Assessment

If successfully exploited, the attacker may obtain arbitrary code execution as the victim or cause an unintended user-writable file to be overwritten. The resulting access is limited ...[truncated 386 chars]

Remediation
View remediation

Remediation Suggestions

  • Create a private temporary directory with mktemp -d instead of using a fixed filename.
  • Set a restrictive umask, such as umask 077, before creating temporary files.
  • Verify that the downloaded path is a regular file owned by the current user and not a symbolic link.
  • Verify a pinned checksum or signature before execution.
  • Execute the verified file from the private temporary directory.
  • Install cleanup handling with a shell trap so temporary content is deleted on success, failure, or interruption.
  • Avoid separating download and execution through a predictable shared path.

T09 · Insecure Skill Coding Practices

Warning
Location
references/02-setup.md:52
Finding

Authentication Output Written to a Predictable Shared Temporary Log

Content
View full analysis

Vulnerability Details

File Location: references/02-setup.md:52-55
Vulnerability Type: Insecure handling of temporary authentication data
Risk Level: Medium

Complete Code Snippet:

bash
dws auth login --device > /tmp/dws-auth.log 2>&1 &
# Read the log to obtain the user code and link
sleep 2; cat /tmp/dws-auth.log

Technical Analysis

The device authentication process redirects its complete standard output and standard error streams to the predictable shared path /tmp/dws-auth.log. The documented output includes a temporary device user code and verification URL.

The file is not securely created, its permissions are not explicitly restricted, and it is not removed after authentication. Its effective permissions depend on the user's current umask. Shell redirection may also follow a pre-existing symbolic link where operating-system protections permit it, potentially truncating another user-writable file.

The documentation launches the authentication process in the background without capturing its process identifier or defining cleanup behavior. The primary security issue, however, is storage of authentication-related output in a predictable shared location.

Attack Path

  1. A local attacker monitors the predictable /tmp/dws-auth.log path or prepares a conflicting filesystem object at that location.
  2. The victim runs the documented device authentication command.
  3. The CLI writes the user code, verification URL, status messages, and any diagnostic output to the shared path.
  4. If file permissions allow local reading, the attacker obtains the temporary authorization information.
  5. The attacker may attempt to interfere with the device authorization flow or use the disclosed information in social-engineering or session-confusion attacks.
  6. Alternatively, where symbolic-link protections permit it, shell redirection may truncate an unintended file writable by the victim.

Possess ...[truncated 933 chars]

Remediation
View remediation

Remediation Suggestions

  • Create a private temporary directory using mktemp -d.
  • Set umask 077 before creating the authentication log.
  • Store the log inside the private directory with mode 0600.
  • Capture the background process identifier and wait for or terminate the intended process explicitly.
  • Remove the log and temporary directory immediately after authentication succeeds or fails.
  • Avoid storing the device code when the CLI can display it directly in a controlled terminal.
  • Document that device codes and verification URLs must not be shared.
  • Reject pre-existing paths and symbolic links rather than redirecting to a fixed filename.
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (33)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · CHANGELOG.md (reported line 15)May include surrounding context.

md
### 修复
- 澄清"只读"措辞:明确"只读"指不改动钉钉云端数据,归档/镜像/音频下载为本地落盘显式操作,消除文档与行为不一致(SkillSpector 审计反馈)
- 依赖表安装命令改为先下载到 `/tmp` 再 `sh` 执行,与 `references/02-setup.md` 一致,去除 `curl | sh` 直接执行远端脚本
- PATH 配置命令补充说明:会修改 `~/.zshrc` 持久配置,并给出手动配置替代方案
- 「本地归档与增量同步」章节新增隐私与合规提示:归档/镜像内容可能含敏感信息,勿提交公开仓库或共享目录

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Although framed as a thin read wrapper, the skill persists sensitive meeting content to archive/, tracks state in index.json, can auto-run mirroring to another destination, and may download audio locally. In the context of AI meeting minutes, this materially increases confidentiality risk because transcripts, action items, and audio can be copied into less controlled storage and retained indefinitely.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Although framed as a thin read wrapper, the skill persists sensitive meeting content to archive/, tracks state in index.json, can auto-run mirroring to another destination, and may download audio locally. In the context of AI meeting minutes, this materially increases confidentiality risk because transcripts, action items, and audio can be copied into less controlled storage and retained indefinitely.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
93% confidence
Finding

The skill instructs users to fetch and execute an installation script from a remote GitHub URL via curl followed by sh. Even though it avoids a direct pipe, it still results in executing unverified remote code, so compromise of the upstream repository, branch, CDN path, or network trust chain could lead to arbitrary code execution on the user's machine.

Content

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

| python3(同步脚本用) | macOS 通常自带;如缺失 brew install python | | curl(安装脚本用) | macOS 通常自带;如缺失 brew install curl |

安装 dws(先落到临时文件再执行,避免 curl | sh 直接执行远端脚本):

bash
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.sh -o /tmp/dws-install.sh

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 · references/01-commands.md (reported line 92)May include surrounding context.

md
- 逐字稿里的「发言人 1 / 发言人 2」是钉钉默认编号,声纹匹配(speaker 写操作)不在薄壳范围;要人名需在钉钉 App 内手动匹配。
- 所有时间字段为 ISO 8601(`startTimeISO` 等),增量同步以 `startTimeISO` 作锚点。
- 私有化/自建应用 Access Token 方式不在本 skill 范围;本 skill 面向个人账号 OAuth(device 模式)。

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 · references/02-setup.md (reported line 94)May include surrounding context.

md
- 逐字稿里的「发言人 1 / 发言人 2」是钉钉默认编号,声纹匹配(speaker 写操作)不在薄壳范围;要人名需在钉钉 App 内手动匹配。
- 所有时间字段为 ISO 8601(`startTimeISO` 等),增量同步以 `startTimeISO` 作锚点。
- 私有化/自建应用 Access Token 方式不在本 skill 范围;本 skill 面向个人账号 OAuth(device 模式)。

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Automatic post-sync mirroring to an external folder introduces a data exfiltration or oversharing risk because sensitive meeting artifacts are copied outside the primary archive as a side effect. The changelog notes convenience and failure behavior, but this entry does not indicate a strong user-facing warning or consent checkpoint for the new default replication behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The changelog explicitly acknowledges that prior 'read-only' wording was inaccurate because the skill writes data locally via archiving, mirroring, and audio download. Mislabeling write-capable behavior as read-only can cause unsafe use in sensitive environments, especially when the data includes transcripts, summaries, todos, and audio that may contain confidential information.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The changelog shows the skill now performs local archiving, mirroring to external folders, and optional audio downloads, while the metadata still describes it as a query/read wrapper. This scope drift is security-relevant because users and orchestration systems may grant or invoke the skill under a lower-risk 'read-only' assumption, even though it can now persist and replicate sensitive meeting content locally.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The third-party dependency description and setup requirements are written only in Chinese, which imposes a language constraint in the skill's user-facing text without any opt-in or alternative language. This can violate language/locale policy expectations when the skill otherwise presents itself in English and does not document that it is intended only for Chinese-speaking or region-specific users.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill exercises shell, network, and local file read/write capabilities but does not declare any explicit tool scope or permission boundaries. That makes its effective privilege set ambiguous and increases the chance an agent will run file-system or network-affecting operations the user did not expect, especially because the skill also includes archive and mirror workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This section explicitly documents commands to retrieve full transcripts and audio download URLs, which are highly sensitive content sources, but provides no privacy, authorization, or data-handling warning. In a read-only data access skill, normalizing access to raw meeting content without guardrails increases the chance of misuse, over-collection, or accidental disclosure of confidential conversations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The setup guide instructs users to download and immediately execute a remote shell script via curl | sh style workflow, which gives the remote source code execution on the user's machine without prior integrity verification or a clear warning about trust and system changes. Even if the source is an official repository, compromise of the repo, branch, CDN path, or transport endpoint could turn this into a supply-chain execution vector.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This Python code accesses the user's recent hearing/meeting records and AI summaries via the dws minutes commands, which can involve sensitive personal or organizational content. While the script prints progress messages, it does not disclose that it will fetch potentially sensitive summaries from the user's account or explain the privacy impact.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/minutes_extract_todos.py (reported line 34)May include surrounding context.

python
print(f"[dry-run] {' '.join(cmd)}")
        return None
    try:
        result = subprocess.run(
            cmd, capture_output=True, text=True, timeout=60
        )
        if result.returncode != 0:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/minutes_recent_summary.py (reported line 34)May include surrounding context.

python
print(f"[dry-run] {' '.join(cmd)}")
        return None
    try:
        result = subprocess.run(
            cmd, capture_output=True, text=True, timeout=60
        )
        if result.returncode != 0:

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The --output parameter allows arbitrary local file paths, enabling the script to write sensitive merged summaries anywhere the current user has permissions. In an agent or automation context, this can be abused to overwrite user files, place data in insecure locations, or create unintended persistence beyond the skill's stated read-oriented purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This script persists merged AI meeting summaries to a local Markdown file, which expands a nominally read/query workflow into local data storage. Because meeting summaries may contain sensitive business or personal content, writing them to disk increases exposure through local compromise, backup systems, shared directories, or accidental retention.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

When the script writes merged summaries to disk, it does so without any explicit warning that potentially sensitive meeting content is being persisted locally. In practice this raises the risk of inadvertent disclosure because users may not realize that transiently viewed content is now stored in a reusable file.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script explicitly allows the optional export of meta.json, which the docstring itself describes as structured internal data that is excluded by default. In a skill whose stated purpose is read/query access to minutes artifacts, exposing an internal metadata file expands the data surface and can leak identifiers, timestamps, links, speaker mappings, or other sensitive fields not expected by users of the skill.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This read-oriented skill includes functionality to write mirrored copies of meeting artifacts to an arbitrary external destination via --dest or local config, creating persistent replicas outside the authoritative archive. That materially increases exfiltration risk because transcripts, summaries, todos, and optional metadata can be copied into user-chosen folders, external knowledge bases, or sync locations without any policy enforcement or destination restriction in the script.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The natural-language documentation, CLI descriptions, and user-facing messages are written exclusively in Chinese, with no indication that another language is supported or that the locale restriction is intentional and justified. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script advertises and performs automatic mirroring of archived minutes data to an external folder, which exceeds a narrow read/query wrapper role and creates an additional exfiltration/copy channel for sensitive meeting data. Even if intended as backup, duplicating transcripts, summaries, todos, and metadata to another location increases exposure and weakens least-privilege expectations.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/sync.py (reported line 57)May include surrounding context.

python
print(f"  [dry-run] {' '.join(cmd)}")
        return None
    try:
        proc = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
    except subprocess.TimeoutExpired:
        print(f"  [timeout] {' '.join(cmd)}", file=sys.stderr)
        return None

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The auto_mirror function operationalizes copying archived minutes data to an outside folder through a second script, which is not necessary for core minutes-reading/query behavior. This additional data propagation path increases confidentiality risk, especially because archived content includes transcripts, summaries, todos, and possibly audio metadata.

Content

No source excerpt is available for this finding.