Back to skill

Security audit

dingtalk-auto-reply

Security checks for vulnerabilities and agentic risk

Overview

This skill is disclosed as a DingTalk auto-replier, but it needs Review because it can persistently run in the background, read workplace context and local data, and send messages as the user without per-message approval.

Install only if you intentionally want a background tool that can monitor DingTalk, read related workplace/local context, and send single-chat replies as you. Use DRY_RUN and TEST_MODE first, disable or narrow Bash/web/local-code/gbrain access where possible, avoid enabling startup persistence until you understand the VBS watchdog, and make sure you have a way to remove the Startup launcher and PATH changes.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (3)

T06 · System Persistence

Error
Location
dingtalk_unread_monitor.py:230
Finding

Automatic Installation of a Hidden Login-Persistence Watchdog

Content
View full analysis
0 Then MsgBox "DingTalk launche ...[truncated 2554 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
gen_launcher.py:184
Finding

Persistent Modification of the Current User PATH During Monitor Setup

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
reply.py:482
Finding

Untrusted DingTalk Content Reaches an Agent with Permission Bypass, Shell, File, and Network Capabilities

Content
View full analysis
" --format json 2. dws chat message list-by-sender --sender-user-id --start "" --end "" --limit 20 --format json 3. Answer using the retrieved records. ``` The vision agent also uses permission-bypass mode: ```python permission_mode="bypassPermissions", ``` ### Technical Analysis Incoming DingTalk messages, conversation history, images, retrieved table data, local workspace context, and optional knowledge-base results are processed by an LLM agent. Message text and retrieved content are untr ...[truncated 3380 chars]
Remediation
View remediation
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (124)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill is designed to send impersonated replies and retrieve local/chat-derived context, but the README does not prominently warn about privacy, consent, reputational harm, and account-impact risks. Users may enable it without understanding that it can act as them and consult sensitive data to craft messages.

Content

No source excerpt is available for this finding.

Ssd 4

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documented workflow is intentionally deceptive: it replies in the user's voice, silently consults private records, and specifically says not to reveal the lookup. This strips recipients of context about how the answer was produced and enables covert surveillance-backed impersonation in workplace communications.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README states that reply generation and image recognition are sent through the CodeBuddy Agent SDK backend, but it does not clearly disclose that chat text and image contents may leave the local machine for processing. This creates a significant privacy and compliance risk, especially for workplace conversations and images.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation explicitly allows the agent to query colleague contact records and message history via dws in order to formulate replies. That exceeds a narrow auto-reply scope and grants access to private organizational communications, creating privacy, surveillance, and unauthorized-use risks.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Allowing the agent to invoke Bash to query dws contact and sender history provides a broader, more powerful capability set than is needed for auto-reply. Shell-mediated access can enable unreviewed data gathering and makes it easier for prompts or tool misuse to traverse private workplace records without user awareness.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill is explicitly designed to inspect coworkers' chat/contact history and then generate replies as if written by the user. Combining covert data retrieval with impersonated messaging is dangerous because it can disclose private workplace information, violate consent expectations, and produce authoritative-seeming statements based on sensitive records.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的核心能力是“监听钉钉未读 + AI 自动回复/提醒”,涉及钉钉会话处理、消息判断、回复生成与通知行为。但提供的代码片段完全没有出现钉钉、会话、消息、微信、回复生成或触发处理逻辑。相反,它仅执行本地环境配置工作:枚举候选 Python、通过子进程测试是否安装 codebuddy-agent-sdk、导入 runtime 获取默认配置、读取和写入 .env。虽然这类脚本可能是整个技能的辅助安装组件,但就该代码片段本身而言,其实际行为与声明用途明显不一致,且包含未在声明中体现的本地环境探测与配置写入能力。因此应判定为描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明的核心功能是“监听钉钉未读消息并自动回复或提醒”,但提供的代码文件 vision.py 仅实现视觉识别层:读取图片路径,构造多模态消息,请求 CodeBuddy SDK 生成图片中文描述,并支持批量图片处理。代码没有任何钉钉会话读取、消息监听、自动发送回复、微信提醒、联系人名单过滤等逻辑,也未体现相关触发器或资源访问。该代码的主要目的与声明用途明显不一致,属于实质性描述与行为不匹配。

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill is designed to send AI-generated messages as the user and even includes a recovery path that can true-send missed replies, but it lacks a prominent up-front warning about impersonation, external communication, privacy exposure, and business risk. Users could enable or invoke it without understanding that it may autonomously speak on their behalf.

Content

No source excerpt is available for this finding.

Ssd 1

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The core documented behavior is to have AI automatically reply in the user's identity while suppressing self-identification and using bypassed permissions. This is deceptive impersonation by design, and if abused it can mislead coworkers, authorize actions falsely, disclose sensitive information, or create legal and workplace harm.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The top-level description immediately frames the skill as useful automation, but does not lead with a short warning that it continuously monitors chats, sends content to AI backends, and may transmit replies externally. For a skill that acts in the user's identity, this omission materially increases misuse risk.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
82% confidence
Finding

The setup flow explicitly writes SDK environment declarations into .env, and elsewhere the document includes API key usage in the same private config. Consolidating runtime routing and credentials in one file is operationally convenient but increases the risk of secret exposure through accidental reads, logs, or overly broad agent file access.

Content

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

├── gen_launcher.py # 启动器生成器(本机自动生成 Startup .vbs,.vbs 不随包分发) ├── dingtalk-helper-backup.md # 【方案B·人设干净部署模板】dingtalk-helper.md 的占位版(无私人数据),随 skill 移植;新机器未注册 agent 时自动兜底注入 ├── _validate.py # 自测脚本(7 模式:集成 / --inject / --test-guard / --test-construct / --test-statemachine / --test-mcp / --env,不真发回复;--env 做环境预检) ├── _setup_env.py # 安装脚本:探测并写入 SDK 运行环境(CODEBUDDY_SDK_PYTHON 等)到 .env ├── recover_missed.py # 补发漏掉的消息(监控曾宕机/DRY_RUN 时,手动拉未读并代复) └── stop_monitor.ps1 # 精确结束本脚本 python(仅停进程,Windows 用)

text

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
N_NAMES`),同事/名单用中性占位(如「同事甲」)或 `.env` 变量,禁止把真实姓名写进 `.py` 注释、`_validate.py` 测试样例、`SKILL.md` 正文等任何位置。改代码后自查:凡 `温*`/`蔡*`/真实拼音全名等一律清零。

Ssd 1

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The prompt-locking explicitly forces the model to pose as a normal employee and forbids it from behaving like an assistant. That is an intentional deception mechanism designed to conceal AI involvement and increases the chance of persuasive fraudulent communication.

Content

No source excerpt is available for this finding.

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

This duplicate finding points to the same behavior: implicit access to global MCP configuration and tokens. In the context of an autonomous reply agent, silent inheritance of external service credentials is dangerous because it broadens both reachable data and exfiltration channels.

Content

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

md
- **⚠️ prompt 指令与工具挂载状态严格一致(防悬空指令)**:拼进 `_MODE_LOCK` 的知识库指令由 `build_knowledge_instruction()` 动态生成,与 `mcp_servers` 挂载判断**都读 `runtime.GBRAIN_GROUNDING` / `runtime.GBRAIN_MCP_URL` 同一实时来源**——gbrain 已挂载则写「必须先调 gbrain、失败回退本地」;gbrain 未挂载(`=0` 或无端点)则明确写「gbrain 未启用、不要调它,直接走本地文件」。绝不会出现「让 agent 去调一个不存在的工具」的悬空指令。
- 控制开关(均在 `runtime.py`,风格对齐 `TABLE_GROUNDING`):
  - `GBRAIN_GROUNDING`(默认开,`=0` 关):关闭则 prompt 切本地文件模式 + 不挂 gbrain 工具,退回纯人设代复(仍保留本地 `产品资料/` `项目文件/` 保底)。
  - `GBRAIN_MCP_URL` / `GBRAIN_MCP_TOKEN`:缺省时**自动从 `~/.workbuddy/mcp.json` 的 `gbrain` 条目读取**(url + Bearer token),单一真源、无需重复填 token;也可用环境变量覆盖。
- `_MODE_LOCK` 与 `dingtalk-helper.md` 均写明「**gbrain 优先(事实性问题必须)、本地文件保底**」:事实性且需要的内容才调 `mcp__gbrain__search`/`query`;**若 gbrain 未接入 / 调用失败 / 超时 / 检索结果为空或明显不对题,回退**到工作空间本地 `产品资料/` `项目文件/` 文档用 Grep/Glob/Read 核实。两路都查不到才如实说「这个我得查下资料确认,稍回你」。本地文件是保底、并非禁用(之前"禁止读本地"的过激限制已撤销)。
- 知识入库:**优先**把产品手册/项目文档/记忆整理进 gbrain(见 gbrain 自身文档)做主检索源;工作空间 `产品资料/` `项目文件/` 文档树**保留作保底回退**,仍随工作空间维护、不要删。

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

This duplicate finding points to the same behavior: implicit access to global MCP configuration and tokens. In the context of an autonomous reply agent, silent inheritance of external service credentials is dangerous because it broadens both reachable data and exfiltration channels.

Content

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

md
- **⚠️ prompt 指令与工具挂载状态严格一致(防悬空指令)**:拼进 `_MODE_LOCK` 的知识库指令由 `build_knowledge_instruction()` 动态生成,与 `mcp_servers` 挂载判断**都读 `runtime.GBRAIN_GROUNDING` / `runtime.GBRAIN_MCP_URL` 同一实时来源**——gbrain 已挂载则写「必须先调 gbrain、失败回退本地」;gbrain 未挂载(`=0` 或无端点)则明确写「gbrain 未启用、不要调它,直接走本地文件」。绝不会出现「让 agent 去调一个不存在的工具」的悬空指令。
- 控制开关(均在 `runtime.py`,风格对齐 `TABLE_GROUNDING`):
  - `GBRAIN_GROUNDING`(默认开,`=0` 关):关闭则 prompt 切本地文件模式 + 不挂 gbrain 工具,退回纯人设代复(仍保留本地 `产品资料/` `项目文件/` 保底)。
  - `GBRAIN_MCP_URL` / `GBRAIN_MCP_TOKEN`:缺省时**自动从 `~/.workbuddy/mcp.json` 的 `gbrain` 条目读取**(url + Bearer token),单一真源、无需重复填 token;也可用环境变量覆盖。
- `_MODE_LOCK` 与 `dingtalk-helper.md` 均写明「**gbrain 优先(事实性问题必须)、本地文件保底**」:事实性且需要的内容才调 `mcp__gbrain__search`/`query`;**若 gbrain 未接入 / 调用失败 / 超时 / 检索结果为空或明显不对题,回退**到工作空间本地 `产品资料/` `项目文件/` 文档用 Grep/Glob/Read 核实。两路都查不到才如实说「这个我得查下资料确认,稍回你」。本地文件是保底、并非禁用(之前"禁止读本地"的过激限制已撤销)。
- 知识入库:**优先**把产品手册/项目文档/记忆整理进 gbrain(见 gbrain 自身文档)做主检索源;工作空间 `产品资料/` `项目文件/` 文档树**保留作保底回退**,仍随工作空间维护、不要删。

Ssd 3

High
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs persistent accumulation of private interaction history and learned context in workspace memory files. Because the skill monitors and auto-replies to workplace conversations, these memory files can contain sensitive personal, operational, or business information and become a high-value local data store.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The migration instructions tell users to populate .env with identifiers and possibly CODEBUDDY_API_KEY for the skill. In the context of an agent that also has file-read capability and broad shell/network access, colocating these secrets in a skill-local file materially raises the chance of credential disclosure or misuse.

Content

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

md
#    # 然后编辑 ~/.codebuddy/agents/dingtalk-helper.md,把 <BOSS_UID>/<ROS_BASE> 等占位填成你自己的钉钉身份与表结构

# 3) 私密配置(不随包分发,新机自建)
cp ~/.workbuddy/skills/dingtalk-auto-reply/.env.example ~/.workbuddy/skills/dingtalk-auto-reply/.env
#    # 编辑 .env 填 BOSS_UID / SELF_OPENDINGTALK_ID / CODEBUDDY_API_KEY(如需)

# 4) dws 入 PATH + 生成本机启动器(幂等,无需重登)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · _setup_env.py (reported line 24)May include surrounding context.

python
import argparse

_SKILL_DIR = os.path.dirname(os.path.abspath(__file__))
_ENV_PATH = os.path.join(_SKILL_DIR, ".env")
_ENV_EXAMPLE = os.path.join(_SKILL_DIR, ".env.example")

# 复用 runtime.parse_env_text(解析 .env 的唯一实现),需先把 skill 目录加入 sys.path

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · _setup_env.py (reported line 104)May include surrounding context.

python
import argparse

_SKILL_DIR = os.path.dirname(os.path.abspath(__file__))
_ENV_PATH = os.path.join(_SKILL_DIR, ".env")
_ENV_EXAMPLE = os.path.join(_SKILL_DIR, ".env.example")

# 复用 runtime.parse_env_text(解析 .env 的唯一实现),需先把 skill 目录加入 sys.path

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · _setup_env.py (reported line 131)May include surrounding context.

python
import argparse

_SKILL_DIR = os.path.dirname(os.path.abspath(__file__))
_ENV_PATH = os.path.join(_SKILL_DIR, ".env")
_ENV_EXAMPLE = os.path.join(_SKILL_DIR, ".env.example")

# 复用 runtime.parse_env_text(解析 .env 的唯一实现),需先把 skill 目录加入 sys.path

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · _validate.py (reported line 466)May include surrounding context.

python
import argparse

_SKILL_DIR = os.path.dirname(os.path.abspath(__file__))
_ENV_PATH = os.path.join(_SKILL_DIR, ".env")
_ENV_EXAMPLE = os.path.join(_SKILL_DIR, ".env.example")

# 复用 runtime.parse_env_text(解析 .env 的唯一实现),需先把 skill 目录加入 sys.path

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · runtime.py (reported line 67)May include surrounding context.

python
import argparse

_SKILL_DIR = os.path.dirname(os.path.abspath(__file__))
_ENV_PATH = os.path.join(_SKILL_DIR, ".env")
_ENV_EXAMPLE = os.path.join(_SKILL_DIR, ".env.example")

# 复用 runtime.parse_env_text(解析 .env 的唯一实现),需先把 skill 目录加入 sys.path

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The backup skill materially expands capabilities beyond the declared auto-reply/reminder purpose by authorizing broad workspace querying and direct message sending. This violates least privilege and increases the chance that a user invoking a narrow messaging skill unintentionally grants access to unrelated project, wiki, and workspace data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill proactively instructs the agent to inspect project tables, wiki content, sheets, todos, and calendars without tying that access to the user’s stated request. This broad autonomous data access creates a natural-language exfiltration surface and can expose sensitive business or personal records unrelated to replying to DingTalk messages.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.