CloudflareWorkers安全配置 workers-security

这个技能专注于Cloudflare Workers的安全配置,包括身份认证、CORS设置、速率限制和输入验证等关键安全措施。用于保护API免受未授权访问、跨域攻击、滥用和漏洞利用。关键词:Cloudflare Workers, 安全, 认证, CORS, 速率限制, 输入验证, API安全。

身份认证 0 次安装 0 次浏览 更新于 3/7/2026

name: workers-security description: Cloudflare Workers 安全,包括认证、CORS、速率限制、输入验证。用于保护API、JWT/API密钥,或遇到认证失败、CORS错误、XSS/注入漏洞时使用。

Cloudflare Workers 安全

保护Workers和API的全面安全模式。

快速安全清单

// 1. 验证所有输入
const validated = schema.parse(await request.json());

// 2. 认证请求
const user = await verifyToken(request.headers.get('Authorization'));
if (!user) return new Response('未授权', { status: 401 });

// 3. 速率限制
const limited = await rateLimiter.check(clientIP);
if (!limited.allowed) return new Response('请求过多', { status: 429 });

// 4. 添加安全头
response.headers.set('X-Content-Type-Options', 'nosniff');
response.headers.set('X-Frame-Options', 'DENY');

// 5. 使用仅HTTPS的cookie
headers.set('Set-Cookie', 'session=xxx; Secure; HttpOnly; SameSite=Strict');

关键规则

  1. 永远不要信任客户端输入 - 验证和清理所有内容
  2. 使用安全密钥 - 存储在Wrangler密钥中,永远不要在代码中
  3. 实施速率限制 - 防止滥用
  4. 设置安全头 - 防止常见攻击
  5. 正确使用CORS - 生产环境中不要使用 *

前10大安全错误

漏洞 症状 预防措施
缺少认证 未授权访问 验证每个请求的令牌
SQL注入 数据泄露 使用D1的参数化查询
XSS 脚本注入 清理输出,设置CSP
CORS配置错误 请求被阻止或开放访问 配置特定来源
代码中的密钥 暴露凭据 使用 wrangler secret
缺少速率限制 DoS漏洞 实施每IP限制
弱令牌 会话劫持 使用crypto.subtle进行签名
缺少HTTPS 数据拦截 强制HTTPS重定向
不安全头 点击劫持、MIME攻击 设置安全头
过多权限 爆炸半径 最小权限原则

认证模式

JWT验证

async function verifyJWT(token: string, secret: string): Promise<{ valid: boolean; payload?: unknown }> {
  try {
    const [headerB64, payloadB64, signatureB64] = token.split('.');

    // 验证签名
    const key = await crypto.subtle.importKey(
      'raw',
      new TextEncoder().encode(secret),
      { name: 'HMAC', hash: 'SHA-256' },
      false,
      ['verify']
    );

    const signature = Uint8Array.from(atob(signatureB64.replace(/-/g, '+').replace(/_/g, '/')), c => c.charCodeAt(0));
    const data = new TextEncoder().encode(`${headerB64}.${payloadB64}`);

    const valid = await crypto.subtle.verify('HMAC', key, signature, data);
    if (!valid) return { valid: false };

    // 解码负载
    const payload = JSON.parse(atob(payloadB64.replace(/-/g, '+').replace(/_/g, '/')));

    // 检查过期时间
    if (payload.exp && Date.now() / 1000 > payload.exp) {
      return { valid: false };
    }

    return { valid: true, payload };
  } catch {
    return { valid: false };
  }
}

API密钥验证

async function validateApiKey(
  request: Request,
  env: Env
): Promise<{ valid: boolean; clientId?: string }> {
  const apiKey = request.headers.get('X-API-Key');
  if (!apiKey) return { valid: false };

  // 哈希密钥进行查找(永远不要存储明文密钥)
  const keyHash = await sha256(apiKey);

  // 在KV或D1中查找
  const client = await env.KV.get(`apikey:${keyHash}`, 'json');
  if (!client) return { valid: false };

  return { valid: true, clientId: client.id };
}

async function sha256(str: string): Promise<string> {
  const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str));
  return [...new Uint8Array(buffer)].map(b => b.toString(16).padStart(2, '0')).join('');
}

输入验证

使用Zod

import { z } from 'zod';

const UserSchema = z.object({
  name: z.string().min(1).max(100),
  email: z.string().email(),
  age: z.number().int().min(0).max(150).optional(),
});

async function handleCreate(request: Request): Promise<Response> {
  try {
    const body = await request.json();
    const user = UserSchema.parse(body);

    // 安全使用验证后的数据
    return Response.json({ success: true, user });
  } catch (error) {
    if (error instanceof z.ZodError) {
      return Response.json({ error: '验证失败', details: error.errors }, { status: 400 });
    }
    throw error;
  }
}

安全头

function addSecurityHeaders(response: Response): Response {
  const headers = new Headers(response.headers);

  // 防止MIME类型嗅探
  headers.set('X-Content-Type-Options', 'nosniff');

  // 防止点击劫持
  headers.set('X-Frame-Options', 'DENY');

  // XSS保护
  headers.set('X-XSS-Protection', '1; mode=block');

  // 内容安全策略
  headers.set('Content-Security-Policy', "default-src 'self'; script-src 'self'");

  // HSTS
  headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');

  // 引用者策略
  headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');

  return new Response(response.body, { status: response.status, headers });
}

CORS配置

const ALLOWED_ORIGINS = ['https://app.example.com', 'https://admin.example.com'];

function handleCORS(request: Request, response: Response): Response {
  const origin = request.headers.get('Origin');

  if (!origin || !ALLOWED_ORIGINS.includes(origin)) {
    return response; // 无CORS头
  }

  const headers = new Headers(response.headers);
  headers.set('Access-Control-Allow-Origin', origin);
  headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  headers.set('Access-Control-Allow-Credentials', 'true');
  headers.set('Access-Control-Max-Age', '86400');

  return new Response(response.body, { status: response.status, headers });
}

何时加载参考

根据任务加载特定参考:

  • 实施认证? → 加载 references/authentication.md
  • CORS问题? → 加载 references/cors-security.md
  • 验证输入? → 加载 references/input-validation.md
  • 管理密钥? → 加载 references/secrets-management.md
  • 速率限制? → 加载 references/rate-limiting.md
  • 安全头? → 加载 references/security-headers.md

模板

模板 目的 使用时
templates/auth-middleware.ts JWT/API密钥认证 添加认证时
templates/cors-handler.ts CORS中间件 处理跨域时
templates/rate-limiter.ts 速率限制 防止滥用时
templates/secure-worker.ts 完整安全设置 启动安全项目时

脚本

脚本 目的 命令
scripts/security-audit.sh 安全审计 ./security-audit.sh <url>

资源