跳转到正文
报告库
用途分类 / 其他用途

Cloudflare Email Service Skill 安全审计

作者说它能做什么(原文)

Implement or troubleshoot Cloudflare Email Sending and Email Routing integrations and their delivery configuration.

第三方安全检查结论

发现安全风险

已检查文件
6
发现的风险
5
会不会运行危险命令?检查是否下载程序后直接运行、让他人远程控制电脑,或藏起要运行的命令。发现 1 项风险
中风险

`npx wrangler` 可能下载并执行未固定版本的软件包

原文依据:3 处
发现了什么

多项检查和账户操作直接使用 `npx wrangler`。如果项目没有本地固定版本,npx 可能从软件包注册表取得并执行当前版本,从而在用户机器上运行并非本仓库固定依赖的代码。

为什么需要注意

被替换、受污染或不兼容的软件包版本可能访问当前项目与可用凭据,或执行错误的 Cloudflare 操作。

风险在条件成立时受源码支持:多个活动指令直接运行未固定版本的 `npx wrangler`。若项目没有本地锁定的 Wrangler,npx 可能取得并执行注册表版本,获得该命令在用户机器上的权限。参考资料虽要求检查已安装版本,但未明确禁止下载。用户可限制网络并要求显示将执行的本地版本。

SKILL.md:27来自说明文档打开原文件
1. **Domain onboarded?** Run `npx wrangler email sending list` to see which domains have email sending enabled. If the domain isn't listed, run `npx wrangler email sending enable userdomain.com` or see [cli-and-mcp.md](references/cli-and-mcp.md) for full setup instructions.2. **Binding configured?** Look for `send_email` in `wrangler.jsonc` (for Workers)3. **postal-mime installed?** Run `npm ls postal-mime` (only needed for receiving/parsing emails)
查看另外 2 个位置
references/cli-and-mcp.md:5来自说明文档打开原文件
For full CLI reference, run `npx wrangler email --help`. For Dashboard setup, see the [getting started docs](https://developers.cloudflare.com/email-service/get-started/).
references/sending.md:5来自说明文档打开原文件
Read the documentation for the selected task before implementing. Inspect the project's installed Wrangler and Agents SDK versions, configuration, and existing conventions first. Run `wrangler types` through the project's package manager after changing bindings; use its generated types instead of handwritten email interfaces. See [Workers TypeScript](https://developers.cloudflare.com/workers/languages/typescript/) for matching types to the project's compatibility date and flags. Do not upgrade dependencies just to match an example.
会不会泄露文件和密钥?检查是否发送含密码或密钥的文件,以及代码里是否直接写了密钥。发现 2 项风险
中风险

示例会把完整邮件正文和身份信息写入日志或持久存储

原文依据:4 处
发现了什么

解析示例把主题和正文输出到日志;存储示例把发件人、收件人、主题、正文及消息标识写入 Durable Object。邮件可能包含密码重置链接、个人资料、客户通信或其他秘密。

为什么需要注意

有日志读取权、Durable Object 访问权或备份访问权的人员和服务可能看到邮件内容;长期保存还会扩大泄露和合规影响。

两个示例分别把解析后的主题、正文和附件数量写入日志,并把发件人、收件人、主题、正文及邮件标识持久化到 Durable Object。它们是教学示例而非自动执行,但照搬后会处理真实入站邮件,可能把敏感通信暴露给日志读者或持久存储访问者。用户可要求正文不记日志、设置保留期与访问控制,并在存储前最小化或加密字段。

references/routing.md:99来自说明文档打开原文件
async email(message, env, ctx) {  const rawBuffer = await new Response(message.raw).arrayBuffer();  const parsed = await PostalMime.parse(rawBuffer);  console.log("Subject:", parsed.subject);  console.log("Text:", parsed.text);  console.log("Attachments:", parsed.attachments.length);}```
查看另外 3 个位置
references/routing.md:126来自说明文档打开原文件
export class MailboxDO extends DurableObject {  async storeEmail(from: string, to: string, subject: string, body: string,                   messageId: string, inReplyTo: string | null) {    this.ctx.storage.sql.exec(      `INSERT INTO emails (sender, recipient, subject, body, message_id, in_reply_to, date, read)       VALUES (?, ?, ?, ?, ?, ?, datetime('now'), 0)`,      from, to, subject, body, messageId, inReplyTo    );  }
references/routing.md:127来自说明文档打开原文件
export class MailboxDO extends DurableObject {  async storeEmail(from: string, to: string, subject: string, body: string,                   messageId: string, inReplyTo: string | null) {    this.ctx.storage.sql.exec(      `INSERT INTO emails (sender, recipient, subject, body, message_id, in_reply_to, date, read)       VALUES (?, ?, ?, ?, ?, ?, datetime('now'), 0)`,      from, to, subject, body, messageId, inReplyTo    );  }
references/routing.md:145来自说明文档打开原文件
    await stub.storeEmail(      message.from,      message.to,      parsed.subject || "(no subject)",      parsed.text || parsed.html || "",      message.headers.get("message-id") || "",      message.headers.get("in-reply-to") || null,    );
中风险

回复正文未经 HTML 转义即插入外发邮件

原文依据:2 处
发现了什么

示例同时把 `replyBody` 作为纯文本和 HTML 使用,其中 HTML 版本直接插入 `<p>`,没有转义或净化。若正文来自收到的邮件、AI 草稿或其他不可信输入,其中的标签、链接或跟踪资源会成为外发 HTML。

为什么需要注意

收件人可能收到攻击者控制的链接、误导性格式或远程跟踪内容;邮件看起来由用户已验证的域名发出,会提高其可信度。

示例把 `replyBody` 原样插入 HTML,同时说明该回复可由用户或代理决定;没有显示 HTML 转义或净化。若该值含不可信标签、链接或远程图片,它们会进入外发 HTML,并可能欺骗收件人或触发跟踪资源。风险取决于 `replyBody` 的来源。用户可要求仅发送纯文本,或在生成 HTML 前采用经过审查的转义/净化,并在发送前人工预览。

references/routing.md:162来自说明文档打开原文件
When a user (or agent) decides to reply, build proper threading headers and send via the `send_email` binding:```typescript// In an HTTP handler or agent tool — not in the email() handlerasync function replyToStoredEmail(env: Env, original: StoredEmail, replyBody: string) {  // Build threading headers (In-Reply-To + References per RFC 2822)  const headers: Record<string, string> = {};  if (original.messageId) {    headers["In-Reply-To"] = original.messageId;    headers["References"] = original.messageId;  }  await env.EMAIL.send({    to: original.sender,    from: original.recipient,    subject: `Re: ${original.subject}`,    text: replyBody,    html: `<p>${replyBody}</p>`,    headers,  });}
查看另外 1 个位置
references/routing.md:174来自说明文档打开原文件
  await env.EMAIL.send({    to: original.sender,    from: original.recipient,    subject: `Re: ${original.subject}`,    text: replyBody,    html: `<p>${replyBody}</p>`,    headers,  });}
会不会删除文件或一直在后台运行?检查是否大范围删除文件、改写磁盘,或设置自动启动。未发现风险
会不会绕过安全保护?检查是否跳过网站安全验证、开放过多文件权限,或取消操作前的确认。发现 2 项风险
中风险

先决条件流程可直接启用域名,真实发送流程可使用当前 Cloudflare 身份执行外部操作

原文依据:5 处
发现了什么

当域名未列出时,Skill 指示运行启用命令;另有 CLI、REST 和 MCP 示例会真正发送邮件。这些动作会修改账户配置、DNS 相关状态或代表用户联系外部收件人,但正文没有统一要求在执行前确认目标域名、账户、收件人和内容。

为什么需要注意

代理选错账户、域名或地址时,可能改变错误域名的邮件设置、消耗额度、泄露邮件内容,或向第三方发送未经批准的信息。

启用域名是先决条件流程中的实际指令,而 CLI/MCP 发送段包含会产生真实外部邮件的命令;本地开发章节也明确说邮件会实际发送。发送片段是示例,并非无条件自动执行,但正文没有在这些操作前统一要求确认当前账户、域名、收件人和正文。用户可要求每次账户变更或发送前单独确认,并使用测试收件人和最小权限令牌。

SKILL.md:27来自说明文档打开原文件
1. **Domain onboarded?** Run `npx wrangler email sending list` to see which domains have email sending enabled. If the domain isn't listed, run `npx wrangler email sending enable userdomain.com` or see [cli-and-mcp.md](references/cli-and-mcp.md) for full setup instructions.2. **Binding configured?** Look for `send_email` in `wrangler.jsonc` (for Workers)
查看另外 4 个位置
references/cli-and-mcp.md:34来自说明文档打开原文件
```bashnpx wrangler email sending enable yourdomain.comnpx wrangler email sending dns get yourdomain.com   # Verify records```
references/cli-and-mcp.md:103来自说明文档打开原文件
## Sending from CLI / Agents```bashnpx wrangler email sending send \  --from "agent@yourdomain.com" \  --to "developer@company.com" \  --subject "Deployment Complete" \  --text "Your Worker was deployed successfully."```
references/cli-and-mcp.md:115来自说明文档打开原文件
```bashcurl "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/email/sending/send" \  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \  --header "Content-Type: application/json" \  --data '{    "to": "developer@company.com",    "from": {"address": "agent@yourdomain.com", "name": "Build Agent"},    "subject": "Deployment Complete",    "text": "Your Worker was deployed successfully."  }'```
references/cli-and-mcp.md:41来自说明文档打开原文件
Add `"remote": true` to send real emails during `wrangler dev`:```jsonc{ "send_email": [{ "name": "EMAIL", "remote": true }] }``````bashnpx wrangler dev```Emails are actually sent — use test addresses you control. Remove `"remote": true` before deploying.
低风险

安装命令没有固定依赖版本

原文依据:1 处
发现了什么

安装命令没有指定依赖版本。同样的命令以后可能下载不同代码,你实际安装的内容可能与这次检查时不同。

为什么需要注意

即使命令和报告没变,以后安装时也可能下载到另一份代码。

这段证据能说明什么

该行确实使用了未带版本号的 `npx wrangler`,但它不是明确的依赖安装步骤;是否下载新包取决于项目中是否已有可解析的 Wrangler 版本及 npx 环境。若本地没有固定版本,用户可要求作者仅使用项目锁文件中的 Wrangler,并禁止自动下载。

这项判断针对展示的代码和适用条件,不表示风险已经实际发生。
SKILL.md:27来自说明文档打开原文件
1. **Domain onboarded?** Run `npx wrangler email sending list` to see which domains have email sending enabled. If the domain isn't listed, run `npx wrangler email sending enable userdomain.com` or see [cli-and-mcp.md](references/cli-and-mcp.md) for full setup instructions.2. **Binding configured?** Look for `send_email` in `wrangler.jsonc` (for Workers)
会不会误导 AI 或隐藏内容?检查工作说明是否要求 AI 忽略你的指令、干扰检查结果,或夹带看不见的文字。未发现风险
会不会偷偷改推广链接或收款方?检查是否强制替换推广链接或收款对象,同时要求隐瞒更改。未发现风险

Skill 逻辑拆解

6 个说明模块

该 Skill 是操作指南,会让代理根据任务选择 Workers 绑定、REST API、Wrangler CLI 或 MCP;它不仅生成代码,也包含启用域名、发送邮件和管理抑制列表等会改变 Cloudflare 账户状态的操作。

查看原文
SKILL.md:37来自说明文档打开原文件
|--------------|------|-----------|| **Send emails from a Cloudflare Worker** | Workers binding (no API keys needed) | [sending.md](references/sending.md) || **Send emails from an AI agent built with [Cloudflare Agents SDK](https://developers.cloudflare.com/agents/)** | `onEmail()` + `replyToEmail()` in Agent class | [sending.md](references/sending.md) || **Send emails from an external app or agent** (Node.js, Go, Python, etc.) | REST API with Bearer token | [rest-api.md](references/rest-api.md) || **Send emails from a coding agent** (Claude Code, Cursor, Copilot, etc.) | MCP tools, wrangler CLI, or REST API | [cli-and-mcp.md](references/cli-and-mcp.md) || **Receive and process incoming emails** (Email Routing) | Workers `email()` handler | [routing.md](references/routing.md) || **Set up Email Sending or Email Routing** | `wrangler email sending enable` / `wrangler email routing enable`, or Dashboard | [cli-and-mcp.md](references/cli-and-mcp.md) || **Improve deliverability, avoid spam folders** | Authentication, content, compliance | [deliverability.md](references/deliverability.md) |

指南明确区分本地模拟与真实投递,并警告 `remote: true` 会在开发期间真正发送邮件。

查看原文
references/cli-and-mcp.md:41来自说明文档打开原文件
Add `"remote": true` to send real emails during `wrangler dev`:```jsonc{ "send_email": [{ "name": "EMAIL", "remote": true }] }``````bashnpx wrangler dev```Emails are actually sent — use test addresses you control. Remove `"remote": true` before deploying.

收件处理示例会解析邮件正文,并提供将发件人、收件人、主题、正文和线程标识持久化到 Durable Object SQLite 的模式。

查看原文
references/routing.md:126来自说明文档打开原文件
export class MailboxDO extends DurableObject {  async storeEmail(from: string, to: string, subject: string, body: string,                   messageId: string, inReplyTo: string | null) {    this.ctx.storage.sql.exec(      `INSERT INTO emails (sender, recipient, subject, body, message_id, in_reply_to, date, read)       VALUES (?, ?, ?, ?, ?, ?, datetime('now'), 0)`,      from, to, subject, body, messageId, inReplyTo    );  }
references/routing.md:139来自说明文档打开原文件
  async email(message, env, ctx) {    const raw = await new Response(message.raw).arrayBuffer();    const parsed = await PostalMime.parse(raw);    const id = env.MAILBOX.idFromName(message.to);    const stub = env.MAILBOX.get(id);    await stub.storeEmail(      message.from,      message.to,      parsed.subject || "(no subject)",      parsed.text || parsed.html || "",      message.headers.get("message-id") || "",      message.headers.get("in-reply-to") || null,    );

“稍后回复”模式要求用户或代理决定回复,并建议人审后发送;这降低了自动外发风险,但并未消除不受信任邮件内容影响 AI 草稿或回复正文的风险。

查看原文
references/routing.md:160来自说明文档打开原文件
### Reply LaterWhen a user (or agent) decides to reply, build proper threading headers and send via the `send_email` binding:
references/routing.md:191来自说明文档打开原文件
- **Store attachments separately** in R2 (binary blobs), with metadata in SQLite.- **Defer heavy work** (AI drafting, notifications) via `ctx.waitUntil()` so the `email()` handler returns quickly.- **Never auto-send from the `email()` handler** in a human-in-the-loop flow. Store a draft, let the user review, then send via a separate action.
从这里开始 · 工作说明SKILL.md
cloudflare-email-service
连线表示工作说明包含的模块,不是实际运行顺序。点击模块可查看原文。

文件引用关系图

10 处引用
哪些文件发起引用引用了什么
连线表示真实的文件引用,不是运行顺序。点击节点可高亮相关连线,并查看具体文件和原文位置。虚线表示还有文件需要定位。
文件与检查记录6 个文件

检查范围与遗漏

逐文件查看涉及的内容

下方列出本次涉及的原文范围;纳入检查不代表已查清所有问题。

  • SKILL.md已纳入全文
  • references/cli-and-mcp.md已纳入全文
  • references/deliverability.md已纳入全文
  • references/rest-api.md已纳入全文
  • references/routing.md已纳入全文
  • references/sending.md已纳入全文

这份报告只针对上方版本。我们看了拿到的代码和说明文件,没有实际运行 Skill,也没有检查它另外安装的软件包。因此,这不是“保证安全”的承诺;换了版本或使用环境,结果也可能不同。

  • SKILL.md工作说明
  • references/cli-and-mcp.md配套文件
  • references/deliverability.md配套文件
  • references/rest-api.md配套文件
  • references/routing.md配套文件
  • references/sending.md配套文件

代码和说明中提到的操作

连接外部网站
SKILL.md:18来自说明文档打开原文件
|--------|----------------|---------|| Cloudflare docs | Cloudflare MCP `docs` tool or URL `https://developers.cloudflare.com/email-service/` | API reference, limits, pricing, latest features || REST API spec | `https://developers.cloudflare.com/api/resources/email_sending` | OpenAPI spec for the Email Sending REST API |
SKILL.md:19来自说明文档打开原文件
| Cloudflare docs | Cloudflare MCP `docs` tool or URL `https://developers.cloudflare.com/email-service/` | API reference, limits, pricing, latest features || REST API spec | `https://developers.cloudflare.com/api/resources/email_sending` | OpenAPI spec for the Email Sending REST API || Workers types | `https://www.npmjs.com/package/@cloudflare/workers-types` | Type signatures, binding shapes |
SKILL.md:20来自说明文档打开原文件
| REST API spec | `https://developers.cloudflare.com/api/resources/email_sending` | OpenAPI spec for the Email Sending REST API || Workers types | `https://www.npmjs.com/package/@cloudflare/workers-types` | Type signatures, binding shapes || Agents SDK docs | [Email agent walkthrough](https://developers.cloudflare.com/agents/examples/email-agent/) | Email handling in Agents SDK |
安装其他软件包
SKILL.md:27来自说明文档打开原文件
1. **Domain onboarded?** Run `npx wrangler email sending list` to see which domains have email sending enabled. If the domain isn't listed, run `npx wrangler email sending enable userdomain.com` or see [cli-and-mcp.md](references/cli-and-mcp.md) for full setup instructions.2. **Binding configured?** Look for `send_email` in `wrangler.jsonc` (for Workers)
references/cli-and-mcp.md:5来自说明文档打开原文件
For full CLI reference, run `npx wrangler email --help`. For Dashboard setup, see the [getting started docs](https://developers.cloudflare.com/email-service/get-started/).
references/cli-and-mcp.md:35来自说明文档打开原文件
```bashnpx wrangler email sending enable yourdomain.comnpx wrangler email sending dns get yourdomain.com   # Verify records
运行命令
references/cli-and-mcp.md:34来自说明文档打开原文件
```bashnpx wrangler email sending enable yourdomain.com
references/cli-and-mcp.md:47来自说明文档打开原文件
```bashnpx wrangler dev
references/cli-and-mcp.md:105来自说明文档打开原文件
```bashnpx wrangler email sending send \
读取密钥或账号配置
references/rest-api.md:5来自说明文档打开原文件
Read the relevant page before building the request. Keep credentials in the project's existing secret or environment-variable mechanism, and inspect the installed client SDK version if one is used.
读取了多少行
724
文件校验值(用于核对版本)
dd1205fc61c7d139fd33fd37383adbd6dda0fd0619936a41a8bbb73ef957cf7a