mcpField
W
workers-security

workers-security

github.com/secondsky安全24087 次安装5 周前更新
代码仓库

关于 workers-security

面向 Cloudflare Workers 和 API 开发者的安全实践指南,整理输入验证、身份验证、限流和安全响应头等模式。还包含专项参考文件、模板和审计脚本。

主要功能

  1. 01输入验证与清理
  2. 02JWT 和 API 密钥验证
  3. 03速率限制与安全响应头
  4. 04CORS 配置建议
  5. 05专项参考文件和代码模板
  6. 06安全审计脚本

适用场景

  1. 01为 Worker 请求添加身份验证
  2. 02保护 API 免受滥用和常见攻击
  3. 03配置跨域访问与安全响应头
  4. 04审查 Worker 项目的安全设置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/secondsky/claude-skills --skill workers-security

安装后在 Claude Code 中输入/workers-security确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
authentication.md
cors-security.md
input-validation.md
rate-limiting.md
secrets-management.md
security-headers.md
scripts/
security-audit.sh
templates/
auth-middleware.ts
cors-handler.ts
rate-limiter.ts
secure-worker.ts

详细介绍

Cloudflare Workers 安全

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

快速安全检查清单

// 1. Validate all input
const validated = schema.parse(await request.json());

// 2. Authenticate requests
const user = await verifyToken(request.headers.get('Authorization'));
if (!user) return new Response('Unauthorized', { status: 401 });

// 3. Rate limit
const limited = await rateLimiter.check(clientIP);
if (!limited.allowed) return new Response('Too Many Requests', { status: 429 });

// 4. Add security headers
response.headers.set('X-Content-Type-Options', 'nosniff');
response.headers.set('X-Frame-Options', 'DENY');

// 5. Use HTTPS-only cookies
headers.set('Set-Cookie', 'session=xxx; Secure; HttpOnly; SameSite=Strict');

关键规则

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

十大安全错误

漏洞症状防范措施
缺少身份验证未经授权的访问对每个请求验证令牌
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('.');

    // Verify signature
    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 };

    // Decode payload
    const payload = JSON.parse(atob(payloadB64.replace(/-/g, '+').replace(/_/g, '/')));

    // Check expiration
    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 };

  // Hash the key for lookup (never store plain keys)
  const keyHash = await sha256(apiKey);

  // Lookup in KV or 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);

    // Safe to use validated data
    return Response.json({ success: true, user });
  } catch (error) {
    if (error instanceof z.ZodError) {
      return Response.json({ error: 'Validation failed', details: error.errors }, { status: 400 });
    }
    throw error;
  }
}

安全标头

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

  // Prevent MIME type sniffing
  headers.set('X-Content-Type-Options', 'nosniff');

  // Prevent clickjacking
  headers.set('X-Frame-Options', 'DENY');

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

  // Content Security Policy
  headers.set('Content-Security-Policy', "default-src 'self'; script-src 'self'");

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

  // Referrer policy
  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; // No CORS headers
  }

  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.tsJWT/API 密钥身份验证添加身份验证时
templates/cors-handler.tsCORS 中间件处理跨源请求时
templates/rate-limiter.ts速率限制防止滥用时
templates/secure-worker.ts完整的安全配置启动安全项目时

脚本

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

资源

评论

支持 Markdown